6 Appendix B: Hash Function

The ABF_FULL_TRAILER and ABF_DELTA_TRAILER structures contain hash fields. The cryptographic hash function used to compute these fields is implementation-specific, with the requirement that the same function be used in computing each hash code for each Address Book Server file in a deployment and that the hash value have a high probability of being unique for each file<13>. The following pseudo code is an example of a cryptographic hash function.

 Define HashContacts as Function With Parameters (
     contacts as ABF_CONTACT []
     numberOfContacts as unsigned integer
     )
 Begin
     Define contactIndex as unsigned integer
     Define hashValue as unsigned integer
  
     hashValue = 0
     For (contactIndex=0; contactIndex<numberOfContacts; contactIndex++)
     Begin
     hashValue = hashValue + HashContact (contacts [contactIndex])
     End
  
     //
     // Return 16 bit hash value 
     //
     Return (hashValue & 0xFFFF) XOR (hashValue >> 16)
 End
  
 Define HashContact as Function With Parameters (
     contact as ABF_CONTACT
 Begin
     Define hashValue as unsigned integer
     Define attributeIndex as unsigned integer
  
     hashValue = HashBytes (contact.Id, SizeOf (contact.Id))
     For (attributeIndex=0; attributeIndex<contact.NumberOfAttributes; attributeIndex++)
     Begin
     hashValue = hashValue + HashContactAttribute (contact.Attributes [attributeIndex])
     End
  
     Return hashValue
 End
  
 Define HashContactAttribute as Function With Parameters (
     contactAttribute as ABF_CONTACT_ATTRIBUTE
     )
 Begin
     // contactAttribute.Length may or may not be a computed field
     // depending upon the type of attribute.
     Return HashBytes (contactAttribute.Data, contactAttribute.Length)
 End
  
 Define HashBytes as Function With Parameters (
     buffer as unsigned char []
     bufferLength as unsigned integer
     )
 Begin
     Define hashValue as unsigned integer
     Define bufferIndex as unsigned integer
     Define c as unsigned char
  
     hashValue = 0
     For (bufferIndex=0; bufferIndex<bufferLength; bufferIndex++) 
     Begin
         c = buffer [bufferIndex]
     hashValue = hashValue + (c << 1) + (c >> 1) + c
     End
  
     Return hashValue
 End