获取字符串的常量哈希码(Uint32或Int32),但要保持在范围之外

huangapple go评论117阅读模式
英文:

How to get constant hashcode (Uint32 or Int32) for a string but being outside of a range

问题

根据这篇文章,字符串的官方 "GetHashCode" 在每次执行时会随机生成,以防止黑客攻击。但我需要将哈希码持久化,所以希望它对于特定字符串始终保持相同。

在同一篇文章中,我看到了获取哈希码的方法,但我想知道是否有更好的解决方案,或者是否有一种可以直接获得哈希码的方法,而不受特定范围的限制(比如0 - 2000之外的Uint32)。

英文:

According to this article the official "GetHashCode" for a string is made randomly per execution to prevent Hacking. But I need to persist the hashcode so I want it to be always the same per specific string.

In the same article I saw a way to get an HashCode but I wonder if there is better solution and/or if there is a way to direcly get a Hash code outside of a specific range (like 0 - 2000)? Any Uint32 ouside of [0-2000].

答案1

得分: 0

  1. **Crc32C.ARM.cs**
  2. using System.Runtime.CompilerServices;
  3. using System.Runtime.InteropServices;
  4. using System.Runtime.Intrinsics.Arm;
  5. namespace DiscountCard.Ext.Mod.CRC32
  6. {
  7. partial class Crc32C
  8. {
  9. public static class ImplARM
  10. {
  11. public static uint Update(uint crc, ReadOnlySpan<byte> input)
  12. {
  13. crc ^= uint.MaxValue;
  14. while (input.Length >= 4)
  15. {
  16. crc = Crc32.ComputeCrc32C(crc, Unsafe.ReadUnaligned<uint>(ref MemoryMarshal.GetReference(input)));
  17. input = input.Slice(sizeof(uint));
  18. }
  19. for (int i = 0; i < input.Length; i++)
  20. {
  21. crc = Crc32.ComputeCrc32C(crc, input[i]);
  22. }
  23. return crc ^ uint.MaxValue;
  24. }
  25. public static uint Update64(uint crc, ReadOnlySpan<byte> input)
  26. {
  27. crc ^= uint.MaxValue;
  28. while (input.Length >= sizeof(ulong))
  29. {
  30. crc = Crc32.Arm64.ComputeCrc32C(crc, Unsafe.ReadUnaligned<ulong>(ref MemoryMarshal.GetReference(input)));
  31. input = input.Slice(sizeof(ulong));
  32. }
  33. if (input.Length >= 4)
  34. {
  35. crc = Crc32.ComputeCrc32C(crc, Unsafe.ReadUnaligned<uint>(ref MemoryMarshal.GetReference(input)));
  36. input = input.Slice(sizeof(uint));
  37. }
  38. for (int i = 0; i < input.Length; i++)
  39. {
  40. crc = Crc32.ComputeCrc32C(crc, input[i]);
  41. }
  42. return crc ^ uint.MaxValue;
  43. }
  44. }
  45. }
  46. }
  47. **Crc32C.X86.cs**
  48. using System.Runtime.CompilerServices;
  49. using System.Runtime.InteropServices;
  50. using System.Runtime.Intrinsics.X86;
  51. namespace DiscountCard.Ext.Mod.CRC32
  52. {
  53. partial class Crc32C
  54. {
  55. public static class ImplX86
  56. {
  57. public static uint Update(uint crc, ReadOnlySpan<byte> input)
  58. {
  59. crc ^= uint.MaxValue;
  60. while (input.Length >= sizeof(uint))
  61. {
  62. crc = Sse42.Crc32(crc, Unsafe.ReadUnaligned<uint>(ref MemoryMarshal.GetReference(input)));
  63. input = input.Slice(sizeof(uint));
  64. }
  65. for (int i = 0; i < input.Length; i++)
  66. {
  67. crc = Sse42.Crc32(crc, (byte)input[i]);
  68. }
  69. return crc ^ uint.MaxValue;
  70. }
  71. public static uint Update64(uint crc, ReadOnlySpan<byte> input)
  72. {
  73. ulong crcl = crc ^ uint.MaxValue;
  74. while (input.Length >= sizeof(ulong))
  75. {
  76. crcl = Sse42.X64.Crc32(crcl, Unsafe.ReadUnaligned<ulong>(ref MemoryMarshal.GetReference(input)));
  77. input = input.Slice(sizeof(ulong));
  78. }
  79. crc = unchecked((uint)crcl);
  80. if (input.Length >= 4)
  81. {
  82. crc = Sse42.Crc32(crc, Unsafe.ReadUnaligned<uint>(ref MemoryMarshal.GetReference(input)));
  83. input = input.Slice(sizeof(uint));
  84. }
  85. for (int i = 0; i < input.Length; i++)
  86. {
  87. crc = Sse42.Crc32(crc, (byte)input[i]);
  88. }
  89. return crc ^ uint.MaxValue;
  90. }
  91. }
  92. }
  93. }
  94. **Crc32C.cs**
  95. #define X86_INTRINSICS
  96. using System.Runtime.CompilerServices;
  97. using System.Runtime.InteropServices;
  98. #if X86_INTRINSICS
  99. using System.Runtime.Intrinsics.X86;
  100. #endif
  101. #if ARM_INTRINSICS
  102. using System.Runtime.Intrinsics.Arm;
  103. #endif
  104. namespace DiscountCard.Ext.Mod.CRC32
  105. {
  106. public static unsafe partial class Crc32C
  107. {
  108. private static uint* table;
  109. private const uint poly = 0x82f63b78u;
  110. private static delegate*<uint, ReadOnlySpan<byte>, uint> ptr;
  111. static Crc32C()
  112. {
  113. #if X86_INTRINSICS
  114. if (Sse42.X64.IsSupported)
  115. {
  116. ptr = &ImplX86.Update64;
  117. goto end_decision;
  118. }
  119. if (Sse42.IsSupported)
  120. {
  121. ptr = &ImplX86.Update;
  122. goto end_decision;
  123. }
  124. #endif
  125. #if ARM_INTRINSICS
  126. if (Crc32.Arm64.IsSupported)
  127. {
  128. ptr = &ImplARM.Update64;
  129. goto end_decision;
  130. }
  131. if (Crc32.IsSupported)
  132. {
  133. ptr = &ImplARM.Update;
  134. goto end_decision;
  135. }
  136. #endif
  137. // FOR NO SPECIFIC OS ///////////
  138. InitializeTable();
  139. if (BitConverter.IsLittleEndian)
  140. {
  141. ptr = &UpdateLittleEndianOptimized;
  142. goto end_decision;
  143. }
  144. ptr = &UpdateNative;
  145. // END OF FOR NO SPECIFIC OS ///
  146. end_decision:;
  147. }
  148. static void InitializeTable()
  149. {
  150. table = (uint*)Marshal.AllocHGlobal(16 * 256 * 4);
  151. for (uint i = 0; i < 256; i++)
  152. {
  153. uint res = i;
  154. for (int t = 0; t < 16; t++)
  155. {
  156. for (int k = 0; k < 8; k++) res = (res & 1) == 1 ? poly ^ (res >> 1) : (res >> 1);
  157. table[(t * 256) + i] = res;
  158. }
  159. }
  160. }
  161. static uint UpdateLittleEndianOptimized(uint crci, ReadOnlySpan<byte> input)
  162. {
  163. // Copyright (C) 2013 Mark Adler
  164. ulong crc;
  165. crc = crci ^ 0xffffffff;
  166. while (input.Length >= sizeof(ulong))
  167. {
  168. crc ^= Unsafe.ReadUnaligned<ulong>(ref MemoryMarshal.GetReference(input));
  169. crc = table[(7 * 256) + (crc & 0xff)] ^
  170. table[(6 * 256) + ((crc >> 8) & 0xff)] ^
  171. table[(5 * 256) + ((crc >> 16) & 0xff)] ^
  172. table[(4 * 256) + ((crc >> 24) & 0xff)] ^
  173. table[(3 * 256) + ((crc >> 32) & 0xff)] ^
  174. table[(2 * 256) + ((crc >> 40) & 0xff)] ^
  175. table[(1 * 256) + ((crc >> 48) & 0xff)] ^
  176. table[(0 * 256) + (crc >> 56)];
  177. input = input.Slice(sizeof(ulong));
  178. }
  179. for (int i = 0; i < input.Length; i++)
  180. {
  181. crc = table[(0 * 256) + ((crc ^ input[i]) & 0xff)] ^ (crc >> 8);
  182. }
  183. return (uint)crc ^ 0xffffffff;
  184. }
  185. static uint UpdateNative(uint crc, ReadOnlySpan<byte> input)
  186. {
  187. crc ^= uint.MaxValue;
  188. for (int i = 0; i < input.Length; i++)
  189. {
  190. crc = table[(0 * 256) + ((crc ^ input[i]) &
  191. <details>
  192. <summary>英文:</summary>
  193. **Crc32C.ARM.cs**
  194. using System.Runtime.CompilerServices;
  195. using System.Runtime.InteropServices;
  196. using System.Runtime.Intrinsics.Arm;
  197. namespace DiscountCard.Ext.Mod.CRC32
  198. {
  199. partial class Crc32C
  200. {
  201. public static class ImplARM
  202. {
  203. public static uint Update(uint crc, ReadOnlySpan&lt;byte&gt; input)
  204. {
  205. crc ^= uint.MaxValue;
  206. while (input.Length &gt;= 4)
  207. {
  208. crc = Crc32.ComputeCrc32C(crc, Unsafe.ReadUnaligned&lt;uint&gt;(ref MemoryMarshal.GetReference(input)));
  209. input = input.Slice(sizeof(uint));
  210. }
  211. for (int i = 0; i &lt; input.Length; i++)
  212. {
  213. crc = Crc32.ComputeCrc32C(crc, input[i]);
  214. }
  215. return crc ^ uint.MaxValue;
  216. }
  217. public static uint Update64(uint crc, ReadOnlySpan&lt;byte&gt; input)
  218. {
  219. crc ^= uint.MaxValue;
  220. while (input.Length &gt;= sizeof(ulong))
  221. {
  222. crc = Crc32.Arm64.ComputeCrc32C(crc, Unsafe.ReadUnaligned&lt;ulong&gt;(ref MemoryMarshal.GetReference(input)));
  223. input = input.Slice(sizeof(ulong));
  224. }
  225. if (input.Length &gt;= 4)
  226. {
  227. crc = Crc32.ComputeCrc32C(crc, Unsafe.ReadUnaligned&lt;uint&gt;(ref MemoryMarshal.GetReference(input)));
  228. input = input.Slice(sizeof(uint));
  229. }
  230. for (int i = 0; i &lt; input.Length; i++)
  231. {
  232. crc = Crc32.ComputeCrc32C(crc, input[i]);
  233. }
  234. return crc ^ uint.MaxValue;
  235. }
  236. }
  237. }
  238. }
  239. **Crc32C.X86.cs**
  240. using System.Runtime.CompilerServices;
  241. using System.Runtime.InteropServices;
  242. using System.Runtime.Intrinsics.X86;
  243. namespace DiscountCard.Ext.Mod.CRC32
  244. {
  245. partial class Crc32C
  246. {
  247. public static class ImplX86
  248. {
  249. public static uint Update(uint crc, ReadOnlySpan&lt;byte&gt; input)
  250. {
  251. crc ^= uint.MaxValue;
  252. while (input.Length &gt;= sizeof(uint))
  253. {
  254. crc = Sse42.Crc32(crc, Unsafe.ReadUnaligned&lt;uint&gt;(ref MemoryMarshal.GetReference(input)));
  255. input = input.Slice(sizeof(uint));
  256. }
  257. for (int i = 0; i &lt; input.Length; i++)
  258. {
  259. crc = Sse42.Crc32(crc, (byte)input[i]);
  260. }
  261. return crc ^ uint.MaxValue;
  262. }
  263. public static uint Update64(uint crc, ReadOnlySpan&lt;byte&gt; input)
  264. {
  265. ulong crcl = crc ^ uint.MaxValue;
  266. while (input.Length &gt;= sizeof(ulong))
  267. {
  268. crcl = Sse42.X64.Crc32(crcl, Unsafe.ReadUnaligned&lt;ulong&gt;(ref MemoryMarshal.GetReference(input)));
  269. input = input.Slice(sizeof(ulong));
  270. }
  271. crc = unchecked((uint)crcl);
  272. if (input.Length &gt;= 4)
  273. {
  274. crc = Sse42.Crc32(crc, Unsafe.ReadUnaligned&lt;uint&gt;(ref MemoryMarshal.GetReference(input)));
  275. input = input.Slice(sizeof(uint));
  276. }
  277. for (int i = 0; i &lt; input.Length; i++)
  278. {
  279. crc = Sse42.Crc32(crc, (byte)input[i]);
  280. }
  281. return crc ^ uint.MaxValue;
  282. }
  283. }
  284. }
  285. }
  286. **Crc32C.cs**
  287. #define X86_INTRINSICS
  288. using System.Runtime.CompilerServices;
  289. using System.Runtime.InteropServices;
  290. #if X86_INTRINSICS
  291. using System.Runtime.Intrinsics.X86;
  292. #endif
  293. #if ARM_INTRINSICS
  294. using System.Runtime.Intrinsics.Arm;
  295. #endif
  296. namespace DiscountCard.Ext.Mod.CRC32
  297. {
  298. public static unsafe partial class Crc32C
  299. {
  300. private static uint* table;
  301. private const uint poly = 0x82f63b78u;
  302. private static delegate*&lt;uint, ReadOnlySpan&lt;byte&gt;, uint&gt; ptr;
  303. static Crc32C()
  304. {
  305. #if X86_INTRINSICS
  306. if (Sse42.X64.IsSupported)
  307. {
  308. ptr = &amp;ImplX86.Update64;
  309. goto end_decision;
  310. }
  311. if (Sse42.IsSupported)
  312. {
  313. ptr = &amp;ImplX86.Update;
  314. goto end_decision;
  315. }
  316. #endif
  317. #if ARM_INTRINSICS
  318. if (Crc32.Arm64.IsSupported)
  319. {
  320. ptr = &amp;ImplARM.Update64;
  321. goto end_decision;
  322. }
  323. if (Crc32.IsSupported)
  324. {
  325. ptr = &amp;ImplARM.Update;
  326. goto end_decision;
  327. }
  328. #endif
  329. // FOR NO SPECIFIC OS ///////////
  330. InitializeTable();
  331. if (BitConverter.IsLittleEndian)
  332. {
  333. ptr = &amp;UpdateLittleEndianOptimized;
  334. goto end_decision;
  335. }
  336. ptr = &amp;UpdateNative;
  337. // END OF FOR NO SPECIFIC OS ///
  338. end_decision:;
  339. }
  340. static void InitializeTable()
  341. {
  342. table = (uint*)Marshal.AllocHGlobal(16 * 256 * 4);
  343. for (uint i = 0; i &lt; 256; i++)
  344. {
  345. uint res = i;
  346. for (int t = 0; t &lt; 16; t++)
  347. {
  348. for (int k = 0; k &lt; 8; k++) res = (res &amp; 1) == 1 ? poly ^ (res &gt;&gt; 1) : (res &gt;&gt; 1);
  349. table[(t * 256) + i] = res;
  350. }
  351. }
  352. }
  353. static uint UpdateLittleEndianOptimized(uint crci, ReadOnlySpan&lt;byte&gt; input)
  354. {
  355. // Copyright (C) 2013 Mark Adler
  356. ulong crc;
  357. crc = crci ^ 0xffffffff;
  358. while (input.Length &gt;= sizeof(ulong))
  359. {
  360. crc ^= Unsafe.ReadUnaligned&lt;ulong&gt;(ref MemoryMarshal.GetReference(input));
  361. crc = table[(7 * 256) + (crc &amp; 0xff)] ^
  362. table[(6 * 256) + ((crc &gt;&gt; 8) &amp; 0xff)] ^
  363. table[(5 * 256) + ((crc &gt;&gt; 16) &amp; 0xff)] ^
  364. table[(4 * 256) + ((crc &gt;&gt; 24) &amp; 0xff)] ^
  365. table[(3 * 256) + ((crc &gt;&gt; 32) &amp; 0xff)] ^
  366. table[(2 * 256) + ((crc &gt;&gt; 40) &amp; 0xff)] ^
  367. table[(1 * 256) + ((crc &gt;&gt; 48) &amp; 0xff)] ^
  368. table[(0 * 256) + (crc &gt;&gt; 56)];
  369. input = input.Slice(sizeof(ulong));
  370. }
  371. for (int i = 0; i &lt; input.Length; i++)
  372. {
  373. crc = table[(0 * 256) + ((crc ^ input[i]) &amp; 0xff)] ^ (crc &gt;&gt; 8);
  374. }
  375. return (uint)crc ^ 0xffffffff;
  376. }
  377. static uint UpdateNative(uint crc, ReadOnlySpan&lt;byte&gt; input)
  378. {
  379. crc ^= uint.MaxValue;
  380. for (int i = 0; i &lt; input.Length; i++)
  381. {
  382. crc = table[(0 * 256) + ((crc ^ input[i]) &amp; 0xff)] ^ (crc &gt;&gt; 8);
  383. }
  384. return crc ^ uint.MaxValue;
  385. }
  386. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  387. public static uint Update(uint crc, ReadOnlySpan&lt;byte&gt; input) =&gt; ptr(crc, input);
  388. }
  389. }
  390. **HOW TO USE?**
  391. **A. For CRC32C**
  392. uint result = Crc32C.Update(0, Encoding.ASCII.GetBytes(&quot;There is no God but Allah&quot;));
  393. MessageBox.Show(result.ToString(&quot;X&quot;)); // result: C16698CA
  394. **B. For CRC32**
  395. Change **poly** from
  396. private const uint poly = 0x82f63b78u;
  397. To
  398. private const uint poly = 0xedb88320u;
  399. uint result = Crc32C.Update(0, Encoding.ASCII.GetBytes(&quot;There is no God but Allah&quot;));
  400. MessageBox.Show(result.ToString(&quot;X&quot;)); // result: 0xFABB17B6
  401. </details>

huangapple
  • 本文由 发表于 2023年6月1日 04:48:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/76377165.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定