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

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