簡體   English   中英

string.GetHashCode()在debug vs release中返回不同的值,我該如何避免這種情況?

[英]string.GetHashCode() returns different values in debug vs release, how do I avoid this?

令我驚訝的是,下面的方法在debug和release中產生了不同的結果:

int result = "test".GetHashCode();

有什么方法可以避免這種情況嗎?

我需要一種可靠的方法來散列字符串,我需要在調試和發布模式下保持一致的值。 如果可能的話,我想避免編寫自己的哈希函數。

為什么會這樣?

僅供參考,反射器給了我:

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), SecuritySafeCritical]
public override unsafe int GetHashCode()
{
    fixed (char* str = ((char*) this))
    {
        char* chPtr = str;
        int num = 0x15051505;
        int num2 = num;
        int* numPtr = (int*) chPtr;
        for (int i = this.Length; i > 0; i -= 4)
        {
            num = (((num << 5) + num) + (num >> 0x1b)) ^ numPtr[0];
            if (i <= 2)
            {
                break;
            }
            num2 = (((num2 << 5) + num2) + (num2 >> 0x1b)) ^ numPtr[1];
            numPtr += 2;
        }
        return (num + (num2 * 0x5d588b65));
    }
}

GetHashCode() 不是你應該用來散列字符串的東西,幾乎100%的時間。 在不知道你在做什么的情況下,我建議你使用實際的哈希算法,比如SHA-1:

using(System.Security.Cryptography.SHA1Managed hp = new System.Security.Cryptography.SHA1Managed()) {
    // Use hp.ComputeHash(System.Text.Encoding.ASCII (or Unicode, UTF8, UTF16, or UTF32 or something...).GetBytes(theString) to compute the hash code.
}

更新:對於更快一點的東西,還有SHA1Cng ,這比SHA1Managed

這是一個比SHA快得多的更好的方法,你可以用它替換修改后的GetHasCode: C#fast hash murmur2

有幾種實現具有不同級別的“非托管”代碼,因此如果您需要完全托管,那么它就在那里,如果您可以使用不安全的,那么它也在那里。

    /// <summary>
    /// Default implementation of string.GetHashCode is not consistent on different platforms (x32/x64 which is our case) and frameworks. 
    /// FNV-1a - (Fowler/Noll/Vo) is a fast, consistent, non-cryptographic hash algorithm with good dispersion. (see http://isthe.com/chongo/tech/comp/fnv/#FNV-1a)
    /// </summary>
    private static int GetFNV1aHashCode(string str)
    {
        if (str == null)
            return 0;
        var length = str.Length;
        // original FNV-1a has 32 bit offset_basis = 2166136261 but length gives a bit better dispersion (2%) for our case where all the strings are equal length, for example: "3EC0FFFF01ECD9C4001B01E2A707"
        int hash = length;
        for (int i = 0; i != length; ++i)
            hash = (hash ^ str[i]) * 16777619;
        return hash;
    }

我想這個實現比這里發布的不安全實現慢。 但它更簡單,更安全。 如果不需要超高速,效果很好。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM