Advertisement
ZeekoSec

MurMurHash3

Apr 7th, 2015
541
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
VB.NET 3.84 KB | None | 0 0
  1. Class Murmur3
  2.     ' 128 bit output, 64 bit platform version
  3.  
  4.     Public Shared READ_SIZE As ULong = 16
  5.     Private Shared C1 As ULong = &H87c37b91114253d5UL
  6.     Private Shared C2 As ULong = &H4cf5ad432745937fL
  7.  
  8.     Private length As ULong
  9.     Private seed As UInteger
  10.     ' if want to start with a seed, create a constructor
  11.     Private h1 As ULong
  12.     Private h2 As ULong
  13.  
  14.     Private Sub MixBody(k1 As ULong, k2 As ULong)
  15.         h1 = h1 Xor MixKey1(k1)
  16.  
  17.         h1 = h1.RotateLeft(27)
  18.         h1 += h2
  19.         h1 = h1 * 5 + &H52dce729
  20.  
  21.         h2 = h2 Xor MixKey2(k2)
  22.  
  23.         h2 = h2.RotateLeft(31)
  24.         h2 += h1
  25.         h2 = h2 * 5 + &H38495ab5
  26.     End Sub
  27.  
  28.     Private Shared Function MixKey1(k1 As ULong) As ULong
  29.         k1 *= C1
  30.         k1 = k1.RotateLeft(31)
  31.         k1 *= C2
  32.         Return k1
  33.     End Function
  34.  
  35.     Private Shared Function MixKey2(k2 As ULong) As ULong
  36.         k2 *= C2
  37.         k2 = k2.RotateLeft(33)
  38.         k2 *= C1
  39.         Return k2
  40.     End Function
  41.  
  42.     Private Shared Function MixFinal(k As ULong) As ULong
  43.         ' avalanche bits
  44.  
  45.         k = k Xor k >> 33
  46.         k *= &Hff51afd7ed558ccdUL
  47.         k = k Xor k >> 33
  48.         k *= &Hc4ceb9fe1a85ec53UL
  49.         k = k Xor k >> 33
  50.         Return k
  51.     End Function
  52.  
  53.     Public Function ComputeHash(bb As Byte()) As Byte()
  54.         ProcessBytes(bb)
  55.         Return Hash
  56.     End Function
  57.  
  58.     Private Sub ProcessBytes(bb As Byte())
  59.         h1 = seed
  60.         Me.length = 0L
  61.  
  62.         Dim pos As Integer = 0
  63.         Dim remaining As ULong = CULng(bb.Length)
  64.  
  65.         ' read 128 bits, 16 bytes, 2 longs in eacy cycle
  66.         While remaining >= READ_SIZE
  67.             Dim k1 As ULong = bb.GetUInt64(pos)
  68.             pos += 8
  69.  
  70.             Dim k2 As ULong = bb.GetUInt64(pos)
  71.             pos += 8
  72.  
  73.             length += READ_SIZE
  74.             remaining -= READ_SIZE
  75.  
  76.             MixBody(k1, k2)
  77.         End While
  78.  
  79.         ' if the input MOD 16 != 0
  80.         If remaining > 0 Then
  81.             ProcessBytesRemaining(bb, remaining, pos)
  82.         End If
  83.     End Sub
  84.  
  85.     Private Sub ProcessBytesRemaining(bb As Byte(), remaining As ULong, pos As Integer)
  86.         Dim k1 As ULong = 0
  87.         Dim k2 As ULong = 0
  88.         length += remaining
  89.  
  90.         ' little endian (x86) processing
  91.         Select Case remaining
  92.             Case 15
  93.                 k2 = k2 Xor CULng(bb(pos + 14)) << 48
  94.                 ' fall through
  95.                 goto case 14
  96.             Case 14
  97.                 k2 = k2 Xor CULng(bb(pos + 13)) << 40
  98.                 ' fall through
  99.                 goto case 13
  100.             Case 13
  101.                 k2 = k2 Xor CULng(bb(pos + 12)) << 32
  102.                 ' fall through
  103.                 goto case 12
  104.             Case 12
  105.                 k2 = k2 Xor CULng(bb(pos + 11)) << 24
  106.                 ' fall through
  107.                 goto case 11
  108.             Case 11
  109.                 k2 = k2 Xor CULng(bb(pos + 10)) << 16
  110.                 ' fall through
  111.                 goto case 10
  112.             Case 10
  113.                 k2 = k2 Xor CULng(bb(pos + 9)) << 8
  114.                 ' fall through
  115.                 goto case 9
  116.             Case 9
  117.                 k2 = k2 Xor CULng(bb(pos + 8))
  118.                 ' fall through
  119.                 goto case 8
  120.             Case 8
  121.                 k1 = k1 Xor bb.GetUInt64(pos)
  122.                 Exit Select
  123.             Case 7
  124.                 k1 = k1 Xor CULng(bb(pos + 6)) << 48
  125.                 ' fall through
  126.                 goto case 6
  127.             Case 6
  128.                 k1 = k1 Xor CULng(bb(pos + 5)) << 40
  129.                 ' fall through
  130.                 goto case 5
  131.             Case 5
  132.                 k1 = k1 Xor CULng(bb(pos + 4)) << 32
  133.                 ' fall through
  134.                 goto case 4
  135.             Case 4
  136.                 k1 = k1 Xor CULng(bb(pos + 3)) << 24
  137.                 ' fall through
  138.                 goto case 3
  139.             Case 3
  140.                 k1 = k1 Xor CULng(bb(pos + 2)) << 16
  141.                 ' fall through
  142.                 goto case 2
  143.             Case 2
  144.                 k1 = k1 Xor CULng(bb(pos + 1)) << 8
  145.                 ' fall through
  146.                 goto case 1
  147.             Case 1
  148.                 k1 = k1 Xor CULng(bb(pos))
  149.                 ' fall through
  150.                 Exit Select
  151.             Case Else
  152.                 Throw New Exception("Something went wrong with remaining bytes calculation.")
  153.         End Select
  154.  
  155.         h1 = h1 Xor MixKey1(k1)
  156.         h2 = h2 Xor MixKey2(k2)
  157.     End Sub
  158.  
  159.     Public ReadOnly Property Hash() As Byte()
  160.         Get
  161.             h1 = h1 Xor length
  162.             h2 = h2 Xor length
  163.  
  164.             h1 += h2
  165.             h2 += h1
  166.  
  167.             h1 = Murmur3.MixFinal(h1)
  168.             h2 = Murmur3.MixFinal(h2)
  169.  
  170.             h1 += h2
  171.             h2 += h1
  172.  
  173.             Dim hash__1 = New Byte(Murmur3.READ_SIZE - 1) {}
  174.  
  175.             Array.Copy(BitConverter.GetBytes(h1), 0, hash__1, 0, 8)
  176.             Array.Copy(BitConverter.GetBytes(h2), 0, hash__1, 8, 8)
  177.  
  178.             Return hash__1
  179.         End Get
  180.     End Property
  181. End Class
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement