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

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

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

**Crc32C.ARM.cs**

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.Arm;

namespace DiscountCard.Ext.Mod.CRC32
{
    partial class Crc32C
    {
        public static class ImplARM
        {
            public static uint Update(uint crc, ReadOnlySpan<byte> input)
            {
                crc ^= uint.MaxValue;
                while (input.Length >= 4)
                {
                    crc = Crc32.ComputeCrc32C(crc, Unsafe.ReadUnaligned<uint>(ref MemoryMarshal.GetReference(input)));
                    input = input.Slice(sizeof(uint));
                }
                for (int i = 0; i < input.Length; i++)
                {
                    crc = Crc32.ComputeCrc32C(crc, input[i]);
                }
                return crc ^ uint.MaxValue;
            }

            public static uint Update64(uint crc, ReadOnlySpan<byte> input)
            {
                crc ^= uint.MaxValue;
                while (input.Length >= sizeof(ulong))
                {
                    crc = Crc32.Arm64.ComputeCrc32C(crc, Unsafe.ReadUnaligned<ulong>(ref MemoryMarshal.GetReference(input)));
                    input = input.Slice(sizeof(ulong));
                }
                if (input.Length >= 4)
                {
                    crc = Crc32.ComputeCrc32C(crc, Unsafe.ReadUnaligned<uint>(ref MemoryMarshal.GetReference(input)));
                    input = input.Slice(sizeof(uint));
                }
                for (int i = 0; i < input.Length; i++)
                {
                    crc = Crc32.ComputeCrc32C(crc, input[i]);
                }
                return crc ^ uint.MaxValue;
            }
        }
    }
}

**Crc32C.X86.cs**

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Intrinsics.X86;

namespace DiscountCard.Ext.Mod.CRC32
{
    partial class Crc32C
    {
        public static class ImplX86
        {
            public static uint Update(uint crc, ReadOnlySpan<byte> input)
            {
                crc ^= uint.MaxValue;
                while (input.Length >= sizeof(uint))
                {
                    crc = Sse42.Crc32(crc, Unsafe.ReadUnaligned<uint>(ref MemoryMarshal.GetReference(input)));
                    input = input.Slice(sizeof(uint));
                }
                for (int i = 0; i < input.Length; i++)
                {
                    crc = Sse42.Crc32(crc, (byte)input[i]);
                }
                return crc ^ uint.MaxValue;
            }

            public static uint Update64(uint crc, ReadOnlySpan<byte> input)
            {
                ulong crcl = crc ^ uint.MaxValue;
                while (input.Length >= sizeof(ulong))
                {
                    crcl = Sse42.X64.Crc32(crcl, Unsafe.ReadUnaligned<ulong>(ref MemoryMarshal.GetReference(input)));
                    input = input.Slice(sizeof(ulong));
                }
                crc = unchecked((uint)crcl);
                if (input.Length >= 4)
                {
                    crc = Sse42.Crc32(crc, Unsafe.ReadUnaligned<uint>(ref MemoryMarshal.GetReference(input)));
                    input = input.Slice(sizeof(uint));
                }
                for (int i = 0; i < input.Length; i++)
                {
                    crc = Sse42.Crc32(crc, (byte)input[i]);
                }
                return crc ^ uint.MaxValue;
            }
        }
    }
}

**Crc32C.cs**

#define X86_INTRINSICS

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

#if X86_INTRINSICS
using System.Runtime.Intrinsics.X86;
#endif
#if ARM_INTRINSICS
using System.Runtime.Intrinsics.Arm;
#endif

namespace DiscountCard.Ext.Mod.CRC32
{
    public static unsafe partial class Crc32C
    {
        private static uint* table;
        private const uint poly = 0x82f63b78u;
        private static delegate*<uint, ReadOnlySpan<byte>, uint> ptr;
        static Crc32C()
        {
#if X86_INTRINSICS
            if (Sse42.X64.IsSupported)
            {
                ptr = &ImplX86.Update64;
                goto end_decision;
            }
            if (Sse42.IsSupported)
            {
                ptr = &ImplX86.Update;
                goto end_decision;
            }
#endif
#if ARM_INTRINSICS
            if (Crc32.Arm64.IsSupported)
            {
                ptr = &ImplARM.Update64;
                goto end_decision;
            }
            if (Crc32.IsSupported)
            {
                ptr = &ImplARM.Update;
                goto end_decision;
            }
#endif
            // FOR NO SPECIFIC OS ///////////
            InitializeTable();
            if (BitConverter.IsLittleEndian)
            {
                ptr = &UpdateLittleEndianOptimized;
                goto end_decision;
            }
            ptr = &UpdateNative;
            // END OF FOR NO SPECIFIC OS ///

        end_decision:;
        }

        static void InitializeTable()
        {
            table = (uint*)Marshal.AllocHGlobal(16 * 256 * 4);
            for (uint i = 0; i < 256; i++)
            {
                uint res = i;
                for (int t = 0; t < 16; t++)
                {
                    for (int k = 0; k < 8; k++) res = (res & 1) == 1 ? poly ^ (res >> 1) : (res >> 1);
                    table[(t * 256) + i] = res;
                }
            }
        }

        static uint UpdateLittleEndianOptimized(uint crci, ReadOnlySpan<byte> input)
        {
            // Copyright (C) 2013 Mark Adler
            ulong crc;

            crc = crci ^ 0xffffffff;
            while (input.Length >= sizeof(ulong))
            {
                crc ^= Unsafe.ReadUnaligned<ulong>(ref MemoryMarshal.GetReference(input));
                crc = table[(7 * 256) + (crc & 0xff)] ^
                      table[(6 * 256) + ((crc >> 8) & 0xff)] ^
                      table[(5 * 256) + ((crc >> 16) & 0xff)] ^
                      table[(4 * 256) + ((crc >> 24) & 0xff)] ^
                      table[(3 * 256) + ((crc >> 32) & 0xff)] ^
                      table[(2 * 256) + ((crc >> 40) & 0xff)] ^
                      table[(1 * 256) + ((crc >> 48) & 0xff)] ^
                      table[(0 * 256) + (crc >> 56)];
                input = input.Slice(sizeof(ulong));
            }
            for (int i = 0; i < input.Length; i++)
            {
                crc = table[(0 * 256) + ((crc ^ input[i]) & 0xff)] ^ (crc >> 8);
            }
            return (uint)crc ^ 0xffffffff;
        }

        static uint UpdateNative(uint crc, ReadOnlySpan<byte> input)
        {
            crc ^= uint.MaxValue;
            for (int i = 0; i < input.Length; i++)
            {
                crc = table[(0 * 256) + ((crc ^ input[i]) &

<details>
<summary>英文:</summary>

**Crc32C.ARM.cs**

	using System.Runtime.CompilerServices;
	using System.Runtime.InteropServices;
	using System.Runtime.Intrinsics.Arm;

	namespace DiscountCard.Ext.Mod.CRC32
	{
		partial class Crc32C
		{
			public static class ImplARM
			{
				public static uint Update(uint crc, ReadOnlySpan&lt;byte&gt; input)
				{
					crc ^= uint.MaxValue;
					while (input.Length &gt;= 4)
					{
						crc = Crc32.ComputeCrc32C(crc, Unsafe.ReadUnaligned&lt;uint&gt;(ref MemoryMarshal.GetReference(input)));
						input = input.Slice(sizeof(uint));
					}
					for (int i = 0; i &lt; input.Length; i++)
					{
						crc = Crc32.ComputeCrc32C(crc, input[i]);
					}
					return crc ^ uint.MaxValue;
				}

				public static uint Update64(uint crc, ReadOnlySpan&lt;byte&gt; input)
				{
					crc ^= uint.MaxValue;
					while (input.Length &gt;= sizeof(ulong))
					{
						crc = Crc32.Arm64.ComputeCrc32C(crc, Unsafe.ReadUnaligned&lt;ulong&gt;(ref MemoryMarshal.GetReference(input)));
						input = input.Slice(sizeof(ulong));
					}
					if (input.Length &gt;= 4)
					{
						crc = Crc32.ComputeCrc32C(crc, Unsafe.ReadUnaligned&lt;uint&gt;(ref MemoryMarshal.GetReference(input)));
						input = input.Slice(sizeof(uint));
					}
					for (int i = 0; i &lt; input.Length; i++)
					{
						crc = Crc32.ComputeCrc32C(crc, input[i]);
					}
					return crc ^ uint.MaxValue;
				}
			}
		}
	}

**Crc32C.X86.cs**

	using System.Runtime.CompilerServices;
	using System.Runtime.InteropServices;
	using System.Runtime.Intrinsics.X86;

	namespace DiscountCard.Ext.Mod.CRC32
	{
		partial class Crc32C
		{
			public static class ImplX86
			{
				public static uint Update(uint crc, ReadOnlySpan&lt;byte&gt; input)
				{
					crc ^= uint.MaxValue;
					while (input.Length &gt;= sizeof(uint))
					{
						crc = Sse42.Crc32(crc, Unsafe.ReadUnaligned&lt;uint&gt;(ref MemoryMarshal.GetReference(input)));
						input = input.Slice(sizeof(uint));
					}
					for (int i = 0; i &lt; input.Length; i++)
					{
						crc = Sse42.Crc32(crc, (byte)input[i]);
					}
					return crc ^ uint.MaxValue;
				}

				public static uint Update64(uint crc, ReadOnlySpan&lt;byte&gt; input)
				{
					ulong crcl = crc ^ uint.MaxValue;
					while (input.Length &gt;= sizeof(ulong))
					{
						crcl = Sse42.X64.Crc32(crcl, Unsafe.ReadUnaligned&lt;ulong&gt;(ref MemoryMarshal.GetReference(input)));
						input = input.Slice(sizeof(ulong));
					}
					crc = unchecked((uint)crcl);
					if (input.Length &gt;= 4)
					{
						crc = Sse42.Crc32(crc, Unsafe.ReadUnaligned&lt;uint&gt;(ref MemoryMarshal.GetReference(input)));
						input = input.Slice(sizeof(uint));
					}
					for (int i = 0; i &lt; input.Length; i++)
					{
						crc = Sse42.Crc32(crc, (byte)input[i]);
					}
					return crc ^ uint.MaxValue;
				}
			}
		}
	}

**Crc32C.cs**

	#define X86_INTRINSICS

	using System.Runtime.CompilerServices;
	using System.Runtime.InteropServices;

	#if X86_INTRINSICS
	using System.Runtime.Intrinsics.X86;
	#endif
	#if ARM_INTRINSICS
	using System.Runtime.Intrinsics.Arm;
	#endif

	namespace DiscountCard.Ext.Mod.CRC32
	{
		public static unsafe partial class Crc32C
		{

			private static uint* table;
			private const uint poly = 0x82f63b78u;
			private static delegate*&lt;uint, ReadOnlySpan&lt;byte&gt;, uint&gt; ptr;
			static Crc32C()
			{
	#if X86_INTRINSICS
				if (Sse42.X64.IsSupported)
				{
					ptr = &amp;ImplX86.Update64;
					goto end_decision;
				}
				if (Sse42.IsSupported)
				{
					ptr = &amp;ImplX86.Update;
					goto end_decision;
				}
	#endif
	#if ARM_INTRINSICS
				if (Crc32.Arm64.IsSupported)
				{
					ptr = &amp;ImplARM.Update64;
					goto end_decision;
				}
				if (Crc32.IsSupported)
				{
					ptr = &amp;ImplARM.Update;
					goto end_decision;
				}
	#endif
                // FOR NO SPECIFIC OS ///////////
				InitializeTable();
				if (BitConverter.IsLittleEndian)
				{
					ptr = &amp;UpdateLittleEndianOptimized;
					goto end_decision;
				}
				ptr = &amp;UpdateNative;
                // END OF FOR NO SPECIFIC OS ///

			end_decision:;
			}

			static void InitializeTable()
			{
				table = (uint*)Marshal.AllocHGlobal(16 * 256 * 4);
				for (uint i = 0; i &lt; 256; i++)
				{
					uint res = i;
					for (int t = 0; t &lt; 16; t++)
					{
						for (int k = 0; k &lt; 8; k++) res = (res &amp; 1) == 1 ? poly ^ (res &gt;&gt; 1) : (res &gt;&gt; 1);
						table[(t * 256) + i] = res;
					}
				}
			}

			static uint UpdateLittleEndianOptimized(uint crci, ReadOnlySpan&lt;byte&gt; input)
			{
				// Copyright (C) 2013 Mark Adler
				ulong crc;

				crc = crci ^ 0xffffffff;
				while (input.Length &gt;= sizeof(ulong))
				{
					crc ^= Unsafe.ReadUnaligned&lt;ulong&gt;(ref MemoryMarshal.GetReference(input));
					crc = table[(7 * 256) + (crc &amp; 0xff)] ^
						  table[(6 * 256) + ((crc &gt;&gt; 8) &amp; 0xff)] ^
						  table[(5 * 256) + ((crc &gt;&gt; 16) &amp; 0xff)] ^
						  table[(4 * 256) + ((crc &gt;&gt; 24) &amp; 0xff)] ^
						  table[(3 * 256) + ((crc &gt;&gt; 32) &amp; 0xff)] ^
						  table[(2 * 256) + ((crc &gt;&gt; 40) &amp; 0xff)] ^
						  table[(1 * 256) + ((crc &gt;&gt; 48) &amp; 0xff)] ^
						  table[(0 * 256) + (crc &gt;&gt; 56)];
					input = input.Slice(sizeof(ulong));
				}
				for (int i = 0; i &lt; input.Length; i++)
				{
					crc = table[(0 * 256) + ((crc ^ input[i]) &amp; 0xff)] ^ (crc &gt;&gt; 8);
				}
				return (uint)crc ^ 0xffffffff;
			}

			static uint UpdateNative(uint crc, ReadOnlySpan&lt;byte&gt; input)
			{
				crc ^= uint.MaxValue;
				for (int i = 0; i &lt; input.Length; i++)
				{
					crc = table[(0 * 256) + ((crc ^ input[i]) &amp; 0xff)] ^ (crc &gt;&gt; 8);
				}
				return crc ^ uint.MaxValue;
			}


			[MethodImpl(MethodImplOptions.AggressiveInlining)]
			public static uint Update(uint crc, ReadOnlySpan&lt;byte&gt; input) =&gt; ptr(crc, input);

		}
	}

**HOW TO USE?**

**A. For CRC32C**

	uint result = Crc32C.Update(0, Encoding.ASCII.GetBytes(&quot;There is no God but Allah&quot;));
	MessageBox.Show(result.ToString(&quot;X&quot;)); // result: C16698CA


**B. For CRC32** 

Change **poly** from

    private const uint poly = 0x82f63b78u;

To

    private const uint poly = 0xedb88320u;



	uint result = Crc32C.Update(0, Encoding.ASCII.GetBytes(&quot;There is no God but Allah&quot;));
	MessageBox.Show(result.ToString(&quot;X&quot;)); // result: 0xFABB17B6


</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:

确定