Implementing Jenkins one-at-a-time hash function in VB.NET

Posted on 16th March 2018

Jenkins one at a time hash is a hash function that produces a 4 byte hash value from a multi-byte in input. This function was developed by Bob Jenkins, based on the Colin Plumb's (a cryptographer who supposedly works for NSA) requirements.

Here is the one at a time has function written by Jenkins using OCI (Oracle Call Interface)

ub4 one_at_a_time(char *key, ub4 len)
{
  ub4 hash, i;
  for (hash=0, i=0; i> 6);
  }
  hash += (hash << 3);
  hash ^= (hash >> 11);
  hash += (hash << 15);
  return (hash & mask);
} 

Here we look at how to implement the above one at a time hash function in VB.NET.

In his program, Jenkins uses the datatype ub4 which is the equivalent of 32 bit unsigned int. But when you implement this function in VB.NET using UInt32 data type, you will get an overflow exception when the left shift operation goes beyond 32 bits.

System.OverflowException

No exception will be raised if you are implementing this on C as the C compilers just discard the extra bits but VB compilers doesn't. There are two ways to get past this error - the first method is to remove integer overflow checks on the whole project. To do this go to Project properties, click Compile and then Advanced Compile Options. Then check the box next to Remove integer overflow checks

Remove Integer Overflow Check

If you want to keep checking for integer overflows in your project, there is a second method by which you define the hash variable as unsigned 64 bit integer (UInt64). After every left shift operation you can use the BitConverter.GetBytes() function to get only the first 32 bits. See below Jenkins one-at-a-time hash function implemented using VB.NET

 Private Function JenkinsHash(ByVal key As Byte(), ByVal length As UInt16)
  Dim hash As UInt64 = 0

  Try
    For i = 0 To length - 1
      hash += key(i)
      hash += hash << 10
      hash = BitConverter.ToUInt32(BitConverter.GetBytes(hash), 0)
      hash = hash Xor (hash >> 6)
    Next

    hash += (hash << 3)
    hash = BitConverter.ToUInt32(BitConverter.GetBytes(hash), 0)
    hash = hash Xor (hash >> 11)
    hash += (hash << 15)
    hash = BitConverter.ToUInt32(BitConverter.GetBytes(hash), 0)
 
    Return hash
 
  Catch ex As Exception
    Return 0
  End Try
 End Function

The above function take two parameters. The first parameter is a byte array and the second parameter is the length(number of elements) in the byte array. This function calculates the hash value of the byte array using Jenkins hash function and returns that hash. In case of any error, it will return hash value as 0.


Post a comment

Comments

Nothing yet..be the first to share wisdom.