y_stringhash_entry.inc 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474
  1. #if defined _INC_y_stringhash
  2. #endinput
  3. #endif
  4. #define _INC_y_stringhash
  5. /*
  6. Legal:
  7. Version: MPL 1.1
  8. The contents of this file are subject to the Mozilla Public License Version
  9. 1.1 the "License"; you may not use this file except in compliance with
  10. the License. You may obtain a copy of the License at
  11. http://www.mozilla.org/MPL/
  12. Software distributed under the License is distributed on an "AS IS" basis,
  13. WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  14. for the specific language governing rights and limitations under the
  15. License.
  16. The Original Code is the YSI framework.
  17. The Initial Developer of the Original Code is Alex "Y_Less" Cole.
  18. Portions created by the Initial Developer are Copyright C 2011
  19. the Initial Developer. All Rights Reserved.
  20. Contributors:
  21. Y_Less
  22. koolk
  23. JoeBullet/Google63
  24. g_aSlice/Slice
  25. Misiur
  26. samphunter
  27. tianmeta
  28. maddinat0r
  29. spacemud
  30. Crayder
  31. Dayvison
  32. Ahmad45123
  33. Zeex
  34. irinel1996
  35. Yiin-
  36. Chaprnks
  37. Konstantinos
  38. Masterchen09
  39. Southclaws
  40. PatchwerkQWER
  41. m0k1
  42. paulommu
  43. udan111
  44. Thanks:
  45. JoeBullet/Google63 - Handy arbitrary ASM jump code using SCTRL.
  46. ZeeX - Very productive conversations.
  47. koolk - IsPlayerinAreaEx code.
  48. TheAlpha - Danish translation.
  49. breadfish - German translation.
  50. Fireburn - Dutch translation.
  51. yom - French translation.
  52. 50p - Polish translation.
  53. Zamaroht - Spanish translation.
  54. Los - Portuguese translation.
  55. Dracoblue, sintax, mabako, Xtreme, other coders - Producing other modes for
  56. me to strive to better.
  57. Pixels^ - Running XScripters where the idea was born.
  58. Matite - Pestering me to release it and using it.
  59. Very special thanks to:
  60. Thiadmer - PAWN, whose limits continue to amaze me!
  61. Kye/Kalcor - SA:MP.
  62. SA:MP Team past, present and future - SA:MP.
  63. Optional plugins:
  64. Gamer_Z - GPS.
  65. Incognito - Streamer.
  66. Me - sscanf2, fixes2, Whirlpool.
  67. */
  68. #include "..\..\YSI_Core\y_utils"
  69. // Note: H_a, H_b, H_c, H_d, H_f and H_g are defined here, H_e in y_amx, H_z in
  70. // y_masteronce, H_u in y_users, H_y in y_timers.
  71. // ===================
  72. // Determine version
  73. // ===================
  74. // Entry.
  75. #define _H (_:_H_1:_H_0
  76. #define _I (_:_H_3:_H_2
  77. #define _H@b (_:_H_1:_H_0
  78. #define _I@b (_:_H_3:_H_2
  79. // Old.
  80. #define _H_0(%0) HASH@bernstein(%0))
  81. #define _H_2(%0) HASHi@bernstein(%0))
  82. // New.
  83. #define _H_1:_H_0<%0> HASh@bernstein(%0))
  84. #define _H_3:_H_2<%0> HAShi@bernstein(%0))
  85. // Entry.
  86. #define _H@f (_:_H0@f:_H1@f
  87. #define _I@f (_:_H2@f:_H3@f
  88. // Old.
  89. #define _H1@f(%0) HASH@fnv1(%0))
  90. #define _H3@f(%0) HASHi@fnv1(%0))
  91. // New.
  92. #define _H0@f:_H1@f<%0> HASh@fnv1(%0))
  93. #define _H2@f:_H3@f<%0> HAShi@fnv1(%0))
  94. // Entry.
  95. #define _H@a (_:_H0@a:_H1@a
  96. #define _I@a (_:_H2@a:_H3@a
  97. // Old.
  98. #define _H1@a(%0) HASH@fnv1a(%0))
  99. #define _H3@a(%0) HASHi@fnv1a(%0))
  100. // New.
  101. #define _H0@a:_H1@a<%0> HASh@fnv1a(%0))
  102. #define _H2@a:_H3@a<%0> HAShi@fnv1a(%0))
  103. // Entry.
  104. #define HASH (_:_H_4:_H_5
  105. #define HASHi (_:_H_6:_H_7
  106. // Old.
  107. #define _H_5(%0,%1) HASH@%0(%1))
  108. #define _H_7(%0,%1) HASHi@%0(%1))
  109. // New.
  110. #define _H_4:_H_5:%0<%1> HASh@%0(%1))
  111. #define _H_6:_H_7:%0<%1> HAShi@%0(%1))
  112. // Empty strings.
  113. #define HASH_:%0(,@,@) 2166136261
  114. #define _Y_HASH_H(%0,%1)(%9) @B%0:@A0:@A1:@A2:@A3:@A4:@A5:@A6:@A7:@A8:@A9:@Aa:@Ab:@Ac:@Ad:@Ae:@Af:@Ag:@Ah:@Ai:@Aj:@Ak:@Al:@Am:@An:@Ao:@Ap:@Aq:@Ar:@As:@At:@Au:@Av:@Aw:@Ax:@Ay:@Az:@AA:@AB:@AC:@AD:@AE:@AF:@AG:@AH:@AI:@AJ:@AK:@AL:@AM:@AN:@AO:@AP:@AQ:@AR:@AS:@AT:@AU:@AV:@AW:@AX:@AY:@AZ:@A_:@A@:@B_:@B%1$(%9)$
  115. #define _Y_HASH_I(%0,%1)(%9) @B%0:@A0:@A1:@A2:@A3:@A4:@A5:@A6:@A7:@A8:@A9:@Aa:@Ab:@Ac:@Ad:@Ae:@Af:@Ag:@Ah:@Ai:@Aj:@Ak:@Al:@Am:@An:@Ao:@Ap:@Aq:@Ar:@As:@At:@Au:@Av:@Aw:@Ax:@Ay:@Az:@Ba:@Bb:@Bc:@Bd:@Be:@Bf:@Bg:@Bh:@Bi:@Bj:@Bk:@Bl:@Bm:@Bn:@Bo:@Bp:@Bq:@Br:@Bs:@Bt:@Bu:@Bv:@Bw:@Bx:@By:@Bz:@A_:@A@:@B_:@B%1$(%9)$
  116. // Bernstein
  117. #define @B0:%9$()$ -1
  118. #define @B1$(<%0>%1) @B2:%0@B3:<>%1
  119. #define @B2:%9<%0>%1) %9(@B2:%0)*33+%1)
  120. #define @B3:(%0)*%1$ -%1
  121. // FNV1
  122. #define @B4:%9$()$ 2166136261
  123. #define @B5$(<%0>%1) @B6:%0@B7:<>%1
  124. #define @B6:%9<%0>%1) %9(@B6:%0)*16777619^%1)
  125. #define @B7:(%0)*%9^%1$ 84696351^%1
  126. // FNV1a
  127. #define @B8:%9$()$ 2166136261
  128. #define @B9$(<%0>%1) (@BA:%0@BB:<>%1>
  129. #define @BA:%9<%0>%1>%2) %9(@BA:%0^%1)*16777619>%2)
  130. #define @BB:(%0^%1)%2>$ 2166136261^%1)%2
  131. // Entries
  132. #define HASh@bernstein(%9) _Y_HASH_H(0,1)(%9)
  133. #define HAShi@bernstein(%9) _Y_HASH_I(0,1)(%9)
  134. #define HASh@fnv1(%9) _Y_HASH_H(4,5)(%9)
  135. #define HAShi@fnv1(%9) _Y_HASH_I(4,5)(%9)
  136. #define HASh@fnv1a(%9) _Y_HASH_H(8,9)(%9)
  137. #define HAShi@fnv1a(%9) _Y_HASH_I(8,9)(%9)
  138. /*
  139. 888b 88 ,ad8888ba, 88
  140. 8888b 88 d8"' `"8b 88
  141. 88 `8b 88 d8' 88
  142. 88 `8b 88 ,adPPYba, 8b db d8 88 ,adPPYYba, ,adPPYba, ,adPPYba, ,adPPYb,88
  143. 88 `8b 88 a8P_____88 `8b d88b d8' 88 "" `Y8 I8[ "" a8P_____88 a8" `Y88
  144. 88 `8b 88 8PP""""""" `8b d8'`8b d8' Y8, ,adPPPPP88 `"Y8ba, 8PP""""""" 8b 88
  145. 88 `8888 "8b, ,aa `8bd8' `8bd8' Y8a. .a8P 88, ,88 aa ]8I "8b, ,aa "8a, ,d88
  146. 88 `888 `"Ybbd8"' YP YP `"Y8888Y"' `"8bbdP"Y8 `"YbbdP"' `"Ybbd8"' `"8bbdP"Y8
  147. */
  148. // ================
  149. // Case sensitive
  150. // ================
  151. // Test for the current character. Numbers MUST be first!
  152. #define @A0:%9$(%10%0)$ @A0:%9$(<%1>'0'%0)$
  153. #define @A1:%9$(%11%0)$ @A1:%9$(<%1>'1'%0)$
  154. #define @A2:%9$(%12%0)$ @A2:%9$(<%1>'2'%0)$
  155. #define @A3:%9$(%13%0)$ @A3:%9$(<%1>'3'%0)$
  156. #define @A4:%9$(%14%0)$ @A4:%9$(<%1>'4'%0)$
  157. #define @A5:%9$(%15%0)$ @A5:%9$(<%1>'5'%0)$
  158. #define @A6:%9$(%16%0)$ @A6:%9$(<%1>'6'%0)$
  159. #define @A7:%9$(%17%0)$ @A7:%9$(<%1>'7'%0)$
  160. #define @A8:%9$(%18%0)$ @A8:%9$(<%1>'8'%0)$
  161. #define @A9:%9$(%19%0)$ @A9:%9$(<%1>'9'%0)$
  162. #define @Aa:%9$(%1a%0)$ @Aa:%9$(<%1>97%0)$
  163. #define @Ab:%9$(%1b%0)$ @Ab:%9$(<%1>98%0)$
  164. #define @Ac:%9$(%1c%0)$ @Ac:%9$(<%1>99%0)$
  165. #define @Ad:%9$(%1d%0)$ @Ad:%9$(<%1>100%0)$
  166. #define @Ae:%9$(%1e%0)$ @Ae:%9$(<%1>101%0)$
  167. #define @Af:%9$(%1f%0)$ @Af:%9$(<%1>102%0)$
  168. #define @Ag:%9$(%1g%0)$ @Ag:%9$(<%1>103%0)$
  169. #define @Ah:%9$(%1h%0)$ @Ah:%9$(<%1>104%0)$
  170. #define @Ai:%9$(%1i%0)$ @Ai:%9$(<%1>105%0)$
  171. #define @Aj:%9$(%1j%0)$ @Aj:%9$(<%1>106%0)$
  172. #define @Ak:%9$(%1k%0)$ @Ak:%9$(<%1>107%0)$
  173. #define @Al:%9$(%1l%0)$ @Al:%9$(<%1>108%0)$
  174. #define @Am:%9$(%1m%0)$ @Am:%9$(<%1>109%0)$
  175. #define @An:%9$(%1n%0)$ @An:%9$(<%1>110%0)$
  176. #define @Ao:%9$(%1o%0)$ @Ao:%9$(<%1>111%0)$
  177. #define @Ap:%9$(%1p%0)$ @Ap:%9$(<%1>112%0)$
  178. #define @Aq:%9$(%1q%0)$ @Aq:%9$(<%1>113%0)$
  179. #define @Ar:%9$(%1r%0)$ @Ar:%9$(<%1>114%0)$
  180. #define @As:%9$(%1s%0)$ @As:%9$(<%1>115%0)$
  181. #define @At:%9$(%1t%0)$ @At:%9$(<%1>116%0)$
  182. #define @Au:%9$(%1u%0)$ @Au:%9$(<%1>117%0)$
  183. #define @Av:%9$(%1v%0)$ @Av:%9$(<%1>118%0)$
  184. #define @Aw:%9$(%1w%0)$ @Aw:%9$(<%1>119%0)$
  185. #define @Ax:%9$(%1x%0)$ @Ax:%9$(<%1>120%0)$
  186. #define @Ay:%9$(%1y%0)$ @Ay:%9$(<%1>121%0)$
  187. #define @Az:%9$(%1z%0)$ @Az:%9$(<%1>122%0)$
  188. #define @AA:%9$(%1A%0)$ @AA:%9$(<%1>65%0)$
  189. #define @AB:%9$(%1B%0)$ @AB:%9$(<%1>66%0)$
  190. #define @AC:%9$(%1C%0)$ @AC:%9$(<%1>67%0)$
  191. #define @AD:%9$(%1D%0)$ @AD:%9$(<%1>68%0)$
  192. #define @AE:%9$(%1E%0)$ @AE:%9$(<%1>69%0)$
  193. #define @AF:%9$(%1F%0)$ @AF:%9$(<%1>70%0)$
  194. #define @AG:%9$(%1G%0)$ @AG:%9$(<%1>71%0)$
  195. #define @AH:%9$(%1H%0)$ @AH:%9$(<%1>72%0)$
  196. #define @AI:%9$(%1I%0)$ @AI:%9$(<%1>73%0)$
  197. #define @AJ:%9$(%1J%0)$ @AJ:%9$(<%1>74%0)$
  198. #define @AK:%9$(%1K%0)$ @AK:%9$(<%1>75%0)$
  199. #define @AL:%9$(%1L%0)$ @AL:%9$(<%1>76%0)$
  200. #define @AM:%9$(%1M%0)$ @AM:%9$(<%1>77%0)$
  201. #define @AN:%9$(%1N%0)$ @AN:%9$(<%1>78%0)$
  202. #define @AO:%9$(%1O%0)$ @AO:%9$(<%1>79%0)$
  203. #define @AP:%9$(%1P%0)$ @AP:%9$(<%1>80%0)$
  204. #define @AQ:%9$(%1Q%0)$ @AQ:%9$(<%1>81%0)$
  205. #define @AR:%9$(%1R%0)$ @AR:%9$(<%1>82%0)$
  206. #define @AS:%9$(%1S%0)$ @AS:%9$(<%1>83%0)$
  207. #define @AT:%9$(%1T%0)$ @AT:%9$(<%1>84%0)$
  208. #define @AU:%9$(%1U%0)$ @AU:%9$(<%1>85%0)$
  209. #define @AV:%9$(%1V%0)$ @AV:%9$(<%1>86%0)$
  210. #define @AW:%9$(%1W%0)$ @AW:%9$(<%1>87%0)$
  211. #define @AX:%9$(%1X%0)$ @AX:%9$(<%1>88%0)$
  212. #define @AY:%9$(%1Y%0)$ @AY:%9$(<%1>89%0)$
  213. #define @AZ:%9$(%1Z%0)$ @AZ:%9$(<%1>90%0)$
  214. #define @A_:%9$(%1_%0)$ @A_:%9$(<%1>95%0)$
  215. #define @A@:%9$(%1@%0)$ @A@:%9$(<%1>64%0)$
  216. #define @B_:%9$(%1\32;%0)$ @B_:%9$(<%1>32%0)$
  217. // ==================
  218. // Case insensitive
  219. // ==================
  220. #define @Ba:%9$(%1A%0)$ @Ba:%9$(<%1>97%0)$
  221. #define @Bb:%9$(%1B%0)$ @Bb:%9$(<%1>98%0)$
  222. #define @Bc:%9$(%1C%0)$ @Bc:%9$(<%1>99%0)$
  223. #define @Bd:%9$(%1D%0)$ @Bd:%9$(<%1>100%0)$
  224. #define @Be:%9$(%1E%0)$ @Be:%9$(<%1>101%0)$
  225. #define @Bf:%9$(%1F%0)$ @Bf:%9$(<%1>102%0)$
  226. #define @Bg:%9$(%1G%0)$ @Bg:%9$(<%1>103%0)$
  227. #define @Bh:%9$(%1H%0)$ @Bh:%9$(<%1>104%0)$
  228. #define @Bi:%9$(%1I%0)$ @Bi:%9$(<%1>105%0)$
  229. #define @Bj:%9$(%1J%0)$ @Bj:%9$(<%1>106%0)$
  230. #define @Bk:%9$(%1K%0)$ @Bk:%9$(<%1>107%0)$
  231. #define @Bl:%9$(%1L%0)$ @Bl:%9$(<%1>108%0)$
  232. #define @Bm:%9$(%1M%0)$ @Bm:%9$(<%1>109%0)$
  233. #define @Bn:%9$(%1N%0)$ @Bn:%9$(<%1>110%0)$
  234. #define @Bo:%9$(%1O%0)$ @Bo:%9$(<%1>111%0)$
  235. #define @Bp:%9$(%1P%0)$ @Bp:%9$(<%1>112%0)$
  236. #define @Bq:%9$(%1Q%0)$ @Bq:%9$(<%1>113%0)$
  237. #define @Br:%9$(%1R%0)$ @Br:%9$(<%1>114%0)$
  238. #define @Bs:%9$(%1S%0)$ @Bs:%9$(<%1>115%0)$
  239. #define @Bt:%9$(%1T%0)$ @Bt:%9$(<%1>116%0)$
  240. #define @Bu:%9$(%1U%0)$ @Bu:%9$(<%1>117%0)$
  241. #define @Bv:%9$(%1V%0)$ @Bv:%9$(<%1>118%0)$
  242. #define @Bw:%9$(%1W%0)$ @Bw:%9$(<%1>119%0)$
  243. #define @Bx:%9$(%1X%0)$ @Bx:%9$(<%1>120%0)$
  244. #define @By:%9$(%1Y%0)$ @By:%9$(<%1>121%0)$
  245. #define @Bz:%9$(%1Z%0)$ @Bz:%9$(<%1>122%0)$
  246. // ============
  247. // Other code
  248. // ============
  249. enum e_HASH_TYPE:
  250. {
  251. hash_bernstein,
  252. hash_fnv1,
  253. hash_fnv1a
  254. }
  255. /*-------------------------------------------------------------------------*//**
  256. * <param name="str">The string to hash.</param>
  257. * <param name="sensitive">Wether the hash is case sensitive or not.</param>
  258. * <returns>
  259. * The reverse Bernstein hash of the string.
  260. * </returns>
  261. * <remarks>
  262. * Based on Bernstein hash, but backwards to match the macros. The only
  263. * characters which can be used in the compile time version of this code are:
  264. * a-z, A-Z, 0-9, _ and space.
  265. *
  266. * native Hash(str[]);
  267. *
  268. * NOW FORWARD AGAIN.
  269. * </remarks>
  270. *//*------------------------------------------------------------------------**/
  271. stock YHash(const str[], bool:sensitive = true, e_HASH_TYPE:type = hash_bernstein, len = cellmax, pack = false)
  272. {
  273. if (str[str[0] == '\1'] == '\0')
  274. {
  275. // NULL.
  276. switch (type)
  277. {
  278. case hash_fnv1:
  279. return 2166136261;
  280. case hash_fnv1a:
  281. return 2166136261;
  282. default:
  283. return -1;
  284. }
  285. }
  286. P:3("YHash called: \"%s\", %i, %i, %i, %i", str, _:sensitive, _:type, len, pack);
  287. len = min(len, strlen(str));
  288. new
  289. i = 0;
  290. if (str[0] > 255)
  291. {
  292. switch (type)
  293. {
  294. case hash_bernstein:
  295. {
  296. new
  297. hash = -1;
  298. if (sensitive)
  299. {
  300. while (i != len)
  301. {
  302. hash = hash * 33 + str{i++};
  303. }
  304. }
  305. else
  306. {
  307. while (i != len)
  308. {
  309. pack = str{i++},
  310. hash = hash * 33 + (IS_IN_RANGE(pack, 'A', 'Z' + 1) ? pack | 0x20 : pack);
  311. }
  312. }
  313. return hash;
  314. }
  315. case hash_fnv1:
  316. {
  317. new
  318. hash = 2166136261;
  319. if (sensitive)
  320. {
  321. while (i != len)
  322. {
  323. hash = hash * 16777619 ^ str{i++};
  324. }
  325. }
  326. else
  327. {
  328. while (i != len)
  329. {
  330. pack = str{i++},
  331. hash = hash * 16777619 ^ (IS_IN_RANGE(pack, 'A', 'Z' + 1) ? pack | 0x20 : pack);
  332. }
  333. }
  334. return hash;
  335. }
  336. case hash_fnv1a:
  337. {
  338. new
  339. hash = 2166136261;
  340. if (sensitive)
  341. {
  342. while (i != len)
  343. {
  344. hash = (hash ^ str{i++}) * 16777619;
  345. }
  346. }
  347. else
  348. {
  349. while (i != len)
  350. {
  351. pack = str{i++},
  352. hash = (hash ^ (IS_IN_RANGE(pack, 'A', 'Z' + 1) ? pack | 0x20 : pack)) * 16777619;
  353. }
  354. }
  355. return hash;
  356. }
  357. }
  358. }
  359. else
  360. {
  361. switch (type)
  362. {
  363. case hash_bernstein:
  364. {
  365. new
  366. hash = -1;
  367. if (sensitive)
  368. {
  369. while (i != len)
  370. {
  371. hash = hash * 33 + str[i++];
  372. }
  373. }
  374. else
  375. {
  376. while (i != len)
  377. {
  378. pack = str[i++],
  379. hash = hash * 33 + (IS_IN_RANGE(pack, 'A', 'Z' + 1) ? pack | 0x20 : pack);
  380. }
  381. }
  382. return hash;
  383. }
  384. case hash_fnv1:
  385. {
  386. new
  387. hash = 2166136261;
  388. if (sensitive)
  389. {
  390. while (i != len)
  391. {
  392. hash = hash * 16777619 ^ str[i++];
  393. }
  394. }
  395. else
  396. {
  397. while (i != len)
  398. {
  399. pack = str[i++],
  400. hash = hash * 16777619 ^ (IS_IN_RANGE(pack, 'A', 'Z' + 1) ? pack | 0x20 : pack);
  401. }
  402. }
  403. return hash;
  404. }
  405. case hash_fnv1a:
  406. {
  407. new
  408. hash = 2166136261;
  409. if (sensitive)
  410. {
  411. while (i != len)
  412. {
  413. hash = (hash ^ str[i++]) * 16777619;
  414. }
  415. }
  416. else
  417. {
  418. while (i != len)
  419. {
  420. pack = str[i++],
  421. hash = (hash ^ (IS_IN_RANGE(pack, 'A', 'Z' + 1) ? pack | 0x20 : pack)) * 16777619;
  422. }
  423. }
  424. return hash;
  425. }
  426. }
  427. }
  428. return -1;
  429. }
  430. #include "y_stringhash_bernstein"
  431. #include "y_stringhash_fnv1a"
  432. #include "y_stringhash_fnv1"
  433. #if defined YSI_TESTS
  434. #include "y_stringhash_tests"
  435. #endif