Mirror of Svelto.ECS because we're a fan of it
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Murmur3.cs 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using System;
  2. /// <summary>
  3. /// Murmur hash.
  4. ///
  5. /// Creates an evenly destributed uint hash from a string.
  6. /// Very fast and fairly unique
  7. /// </summary>
  8. public class Murmur3
  9. {
  10. static public uint MurmurHash3_x86_32(byte[] data, uint length, uint seed)
  11. {
  12. uint nblocks = length >> 2;
  13. uint h1 = seed;
  14. const uint c1 = 0xcc9e2d51;
  15. const uint c2 = 0x1b873593;
  16. //----------
  17. // body
  18. int i = 0 ;
  19. for (uint j = nblocks; j > 0 ; --j)
  20. {
  21. uint k1l = BitConverter.ToUInt32(data, i);
  22. k1l *= c1;
  23. k1l = rotl32(k1l, 15);
  24. k1l *= c2;
  25. h1 ^= k1l;
  26. h1 = rotl32(h1, 13);
  27. h1 = h1 * 5 + 0xe6546b64;
  28. i+=4;
  29. }
  30. //----------
  31. // tail
  32. nblocks <<= 2;
  33. uint k1 = 0;
  34. uint tailLength = length & 3;
  35. if (tailLength == 3)
  36. k1 ^= (uint)data[2 + nblocks] << 16;
  37. if (tailLength >= 2)
  38. k1 ^= (uint)data[1 + nblocks] << 8;
  39. if (tailLength >= 1)
  40. {
  41. k1 ^= data[nblocks];
  42. k1 *= c1; k1 = rotl32(k1, 15); k1 *= c2; h1 ^= k1;
  43. }
  44. //----------
  45. // finalization
  46. h1 ^= length;
  47. h1 = fmix32(h1);
  48. return h1;
  49. }
  50. static uint fmix32(uint h)
  51. {
  52. h ^= h >> 16;
  53. h *= 0x85ebca6b;
  54. h ^= h >> 13;
  55. h *= 0xc2b2ae35;
  56. h ^= h >> 16;
  57. return h;
  58. }
  59. static uint rotl32(uint x, byte r)
  60. {
  61. return (x << r) | (x >> (32 - r));
  62. }
  63. static public bool VerificationTest()
  64. {
  65. byte[] key = new byte[256];
  66. byte[] hashes = new byte[1024];
  67. for (uint i = 0; i < 256; i++)
  68. {
  69. key[i] = (byte)i;
  70. uint result = MurmurHash3_x86_32(key, i, 256 - i);
  71. Buffer.BlockCopy(BitConverter.GetBytes(result), 0, hashes, (int)i * 4, 4);
  72. }
  73. // Then hash the result array
  74. uint finalr = MurmurHash3_x86_32(hashes, 1024, 0);
  75. uint verification = 0xB0F57EE3;
  76. //----------
  77. if (verification != finalr)
  78. {
  79. return false;
  80. }
  81. else
  82. {
  83. System.Diagnostics.Debug.WriteLine("works");
  84. return true;
  85. }
  86. }
  87. }