hash.odin 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. package hash
  2. import "core:mem"
  3. @(optimization_mode="speed")
  4. adler32 :: proc(data: []byte, seed := u32(1)) -> u32 {
  5. ADLER_CONST :: 65521;
  6. a, b: u32 = seed & 0xFFFF, seed >> 16;
  7. #no_bounds_check for x in data {
  8. a = (a + u32(x)) % ADLER_CONST;
  9. b = (b + a) % ADLER_CONST;
  10. }
  11. return (b << 16) | a;
  12. }
  13. @(optimization_mode="speed")
  14. djb2 :: proc(data: []byte) -> u32 {
  15. hash: u32 = 5381;
  16. for b in data {
  17. hash = (hash << 5) + hash + u32(b); // hash * 33 + u32(b)
  18. }
  19. return hash;
  20. }
  21. @(optimization_mode="speed")
  22. fnv32 :: proc(data: []byte) -> u32 {
  23. h: u32 = 0x811c9dc5;
  24. for b in data {
  25. h = (h * 0x01000193) ~ u32(b);
  26. }
  27. return h;
  28. }
  29. @(optimization_mode="speed")
  30. fnv64 :: proc(data: []byte) -> u64 {
  31. h: u64 = 0xcbf29ce484222325;
  32. for b in data {
  33. h = (h * 0x100000001b3) ~ u64(b);
  34. }
  35. return h;
  36. }
  37. @(optimization_mode="speed")
  38. fnv32a :: proc(data: []byte) -> u32 {
  39. h: u32 = 0x811c9dc5;
  40. for b in data {
  41. h = (h ~ u32(b)) * 0x01000193;
  42. }
  43. return h;
  44. }
  45. @(optimization_mode="speed")
  46. fnv64a :: proc(data: []byte) -> u64 {
  47. h: u64 = 0xcbf29ce484222325;
  48. for b in data {
  49. h = (h ~ u64(b)) * 0x100000001b3;
  50. }
  51. return h;
  52. }
  53. @(optimization_mode="speed")
  54. jenkins :: proc(data: []byte) -> u32 {
  55. hash: u32 = 0;
  56. for b in data {
  57. hash += u32(b);
  58. hash += hash << 10;
  59. hash ~= hash >> 6;
  60. }
  61. hash += hash << 3;
  62. hash ~= hash >> 11;
  63. hash += hash << 15;
  64. return hash;
  65. }
  66. @(optimization_mode="speed")
  67. murmur32 :: proc(data: []byte) -> u32 {
  68. c1_32: u32 : 0xcc9e2d51;
  69. c2_32: u32 : 0x1b873593;
  70. h1: u32 = 0;
  71. nblocks := len(data)/4;
  72. p := raw_data(data);
  73. p1 := mem.ptr_offset(p, 4*nblocks);
  74. for ; p < p1; p = mem.ptr_offset(p, 4) {
  75. k1 := (cast(^u32)p)^;
  76. k1 *= c1_32;
  77. k1 = (k1 << 15) | (k1 >> 17);
  78. k1 *= c2_32;
  79. h1 ~= k1;
  80. h1 = (h1 << 13) | (h1 >> 19);
  81. h1 = h1*5 + 0xe6546b64;
  82. }
  83. tail := data[nblocks*4:];
  84. k1: u32;
  85. switch len(tail)&3 {
  86. case 3:
  87. k1 ~= u32(tail[2]) << 16;
  88. fallthrough;
  89. case 2:
  90. k1 ~= u32(tail[2]) << 8;
  91. fallthrough;
  92. case 1:
  93. k1 ~= u32(tail[0]);
  94. k1 *= c1_32;
  95. k1 = (k1 << 15) | (k1 >> 17) ;
  96. k1 *= c2_32;
  97. h1 ~= k1;
  98. }
  99. h1 ~= u32(len(data));
  100. h1 ~= h1 >> 16;
  101. h1 *= 0x85ebca6b;
  102. h1 ~= h1 >> 13;
  103. h1 *= 0xc2b2ae35;
  104. h1 ~= h1 >> 16;
  105. return h1;
  106. }
  107. @(optimization_mode="speed")
  108. murmur64 :: proc(data: []byte) -> u64 {
  109. SEED :: 0x9747b28c;
  110. when size_of(int) == 8 {
  111. m :: 0xc6a4a7935bd1e995;
  112. r :: 47;
  113. h: u64 = SEED ~ (u64(len(data)) * m);
  114. data64 := mem.slice_ptr(cast(^u64)raw_data(data), len(data)/size_of(u64));
  115. for _, i in data64 {
  116. k := data64[i];
  117. k *= m;
  118. k ~= k>>r;
  119. k *= m;
  120. h ~= k;
  121. h *= m;
  122. }
  123. switch len(data)&7 {
  124. case 7: h ~= u64(data[6]) << 48; fallthrough;
  125. case 6: h ~= u64(data[5]) << 40; fallthrough;
  126. case 5: h ~= u64(data[4]) << 32; fallthrough;
  127. case 4: h ~= u64(data[3]) << 24; fallthrough;
  128. case 3: h ~= u64(data[2]) << 16; fallthrough;
  129. case 2: h ~= u64(data[1]) << 8; fallthrough;
  130. case 1:
  131. h ~= u64(data[0]);
  132. h *= m;
  133. }
  134. h ~= h>>r;
  135. h *= m;
  136. h ~= h>>r;
  137. return h;
  138. } else {
  139. m :: 0x5bd1e995;
  140. r :: 24;
  141. h1 := u32(SEED) ~ u32(len(data));
  142. h2 := u32(SEED) >> 32;
  143. data32 := mem.slice_ptr(cast(^u32)raw_data(data), len(data)/size_of(u32));
  144. len := len(data);
  145. i := 0;
  146. for len >= 8 {
  147. k1, k2: u32;
  148. k1 = data32[i]; i += 1;
  149. k1 *= m;
  150. k1 ~= k1>>r;
  151. k1 *= m;
  152. h1 *= m;
  153. h1 ~= k1;
  154. len -= 4;
  155. k2 = data32[i]; i += 1;
  156. k2 *= m;
  157. k2 ~= k2>>r;
  158. k2 *= m;
  159. h2 *= m;
  160. h2 ~= k2;
  161. len -= 4;
  162. }
  163. if len >= 4 {
  164. k1: u32;
  165. k1 = data32[i]; i += 1;
  166. k1 *= m;
  167. k1 ~= k1>>r;
  168. k1 *= m;
  169. h1 *= m;
  170. h1 ~= k1;
  171. len -= 4;
  172. }
  173. // TODO(bill): Fix this
  174. #no_bounds_check data8 := mem.slice_to_bytes(data32[i:])[:3];
  175. switch len {
  176. case 3:
  177. h2 ~= u32(data8[2]) << 16;
  178. fallthrough;
  179. case 2:
  180. h2 ~= u32(data8[1]) << 8;
  181. fallthrough;
  182. case 1:
  183. h2 ~= u32(data8[0]);
  184. h2 *= m;
  185. }
  186. h1 ~= h2>>18;
  187. h1 *= m;
  188. h2 ~= h1>>22;
  189. h2 *= m;
  190. h1 ~= h2>>17;
  191. h1 *= m;
  192. h2 ~= h1>>19;
  193. h2 *= m;
  194. return u64(h1)<<32 | u64(h2);
  195. }
  196. }
  197. @(optimization_mode="speed")
  198. sdbm :: proc(data: []byte) -> u32 {
  199. hash: u32 = 0;
  200. for b in data {
  201. hash = u32(b) + (hash<<6) + (hash<<16) - hash;
  202. }
  203. return hash;
  204. }