C#String.getHashCode()为不同的字符串返回相同的值

时间:2015-04-28 14:08:19

标签: c# visual-studio-2013 visual-studio-debugging

我的应用程序作为Windows服务运行,我将VS2013附加到它的调试过程。我获取了图像文件内容的哈希码,以检查以下方法的差异(在静态类中):

static class FileUtils
{
    public static int GetFileHash(string filePath)
    {
        int hash = 0;
        Logger.WriteLog(ToolTipIcon.Info, "Calculating hash code for {0}", filePath);
        StreamReader sr = new StreamReader(filePath, Encoding.Unicode);
        hash = sr.ReadToEnd().GetHashCode();
        sr.Close();
        return hash;
    }
}

在生产中一直运作良好。但是,对于两个不同的图像,此方法将始终返回2074746262。我试图在winforms应用程序中使用相同的代码和图像重现这一点,但我无法做到。是否存在调试VS2013中的进程会导致此行为的问题?我用完全不同的图像替换了其中一个图像,但它仍然会发生。

4 个答案:

答案 0 :(得分:8)

首先,您应该知道您错误地使用GetHashCode,原因有两个:

  1. 哈希码不是唯一的,只有很好的分布式。存在有限数量的哈希码和无限数量的二进制字符串,因此在物理上不可能为每个字符串生成唯一的哈希码。

  2. 哈希代码算法的详细信息未明确记录,更改,原因似乎与您无关。特别是,这不是我第一次看到它报告string.GetHashCode()在调试器下运行时改变了行为:

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

    话虽如此,似乎有点不寻常的是,三个不同的二进制字符串会在相同的运行时环境中以不同的方式散列,这取决于是否附加了调试器。除了通常不信任GetHashCode之外,我的下一个猜测是,您不会散列您认为自己正在散列的内容。我会在对其进行散列之前将二进制数据本身转储到磁盘,并确认您确实拥有不同的二进制字符串。

答案 1 :(得分:2)

Documentation explicitly calls this out。不要依赖String.GetHashCode是唯一的。你的假设是错误的。

  

如果两个字符串对象相等,则返回GetHashCode方法   相同的价值观但是,没有唯一的哈希码值   每个唯一的字符串值。 不同的字符串可以返回相同的哈希值   代码

答案 2 :(得分:2)

而不是GetHashCode,它绝对不会在所有图像中都是唯一的。根据此链接使用MD5或类似内容:

https://msdn.microsoft.com/en-us/library/s02tk69a%28v=vs.110%29.aspx

答案 3 :(得分:1)

使用GetHasCode检查唯一性将永远不会有效,不能保证每个不同的对象都会提供不同的哈希码。