说我有一个5000字符的文字。我通过散列程序运行它并生成一个40 char长的散列。现在我运行另一个文本blob,10000个字符。它仍然会产生40个字符长的哈希值。对于任何长度的文本都是如此。
我的问题是,如果哈希值都是唯一的,我不能将任何东西压缩成40个字符串吗?
答案 0 :(得分:18)
哈希并不是唯一的。
散列是一种尝试为每个馈送到它的值生成唯一散列的技术,但它不能保证唯一。
良好的散列算法将比错误的散列算法更频繁地重复散列值。此外,散列是一个方向 - 意味着你不能从散列 - >原来的,所以它不适合压缩。
并且:哈希不需要是唯一的。需要通过算法将相同的输入转换为相同的散列。您不使用哈希作为标识符!
答案 1 :(得分:9)
并非所有哈希都保证是唯一的。关于该主题的维基百科条目非常好:http://en.wikipedia.org/wiki/Hash_function
答案 2 :(得分:8)
考虑哈希的一种方法就像人类指纹(哈希有时也被称为指纹)。
你可以将任何人“压缩”成一个(几乎)独特的指纹......但是,你不能仅凭他们的指纹知道是谁。这就像一个哈希,你可以很容易地解决{ {1}},但仅提供hash("abcdef") -> a1b2c3
,您无法轻易告知源数据。
要反转指纹,您需要将指纹与已知a1b2c3
的数据库进行比较(如果未知指纹与Person1匹配,未知指纹属于它们)
使用哈希,你必须做同样的事情 - 你有一个包含所有字符串 - >哈希映射的数据库(称为rainbow table)。然后你用哈希“a1b2c3”查找行,并显示“abcdef”被哈希以获得这个。另一种更常见的方法是简单地尝试每个字符组合,哈希并比较(brute force attack)
最后,虽然人类的指纹是“独一无二的”,但它可能有两个相同,它只是非常不可能 - 它与散列相同......有些散列算法比其他散列算法更容易受到collisions的影响。 / p>
我的问题是,如果哈希值都是唯一的,我不能将任何东西压缩成40个字符串吗?
理论上散列是一种很好的压缩方法,但是除了(例如)10个ASCII字符的数据之外,解压缩是非常不切实际的。你是对的,你可以将任何东西压缩成40个字符的字符串,但你实际上不能解压缩它(甚至理论上也有点延伸..)
答案 3 :(得分:5)
RSA哈希不是唯一的。有一个非常小的(大约1:36 ^ 40)的机会,当你散列两个不同的明文时,你会产生误报。对于大多数应用来说,机会被认为足够小,你可以忽略它,因为平均而言,数百万年才能看到意外碰撞。
答案 4 :(得分:3)
哈希是为了尽可能好地传播,而不是为了唯一性!
当然,达到唯一性是达到100%蔓延, 但无论你的哈希算法有多好,这通常都是不可能的。
引人注目的例子:
例如,C#为每个对象提供一个Int32代码作为HashCode ... 对于Int64也是如此:
Int64 a = Int64.MaxValue;
Int32 myHash = a.GetHashCode();
结论:这里有2 ^ 64种不同的Int64实例,但只有2 ^ 32个哈希码!
因此:Int64的每个哈希值由(平均值)
共享4 294 967 295
其他Int64!
如此独特嘿: - )
答案 5 :(得分:1)
从Pigeonhole Principle的角度考虑这个问题。如果您将n个项目填充到较少数量的桶k中,则必然会有一些桶具有多个项目。所以要回答你的问题,没有哈希不是唯一的。
答案 6 :(得分:1)
不保证哈希是唯一的,但如果您要查找唯一哈希,请查看gperf。它可以为一组预定输入生成唯一的散列函数。
答案 7 :(得分:0)
您可以将任何文本的签名压缩为哈希值,但是您无法反向计算文本为您提供的哈希值。简单地说,找出文本是什么给你的哈希的唯一方法是通过哈希强制文本来尝试找到匹配。
请参阅Wikipedia
答案 8 :(得分:0)
不要被.Net GetHashCode()弄糊涂。它不是很好,因为它只有32位而不是原始问题中的640位(如果每个字符是8位)。
答案 9 :(得分:0)
如果正确使用定义良好的散列函数,实际上可以假设散列结果是唯一的。
问题,你的问题是哈希是单向函数。没有反函数来获取值并返回到原始blob。除非你保留一张包含所有可能原始值的大表(所谓的rainbow table)。
答案 10 :(得分:0)
它们并不是唯一的,但是在您找到具有相同散列的两个不同文档以获得高质量算法之前,您更有可能放弃心脏病发作。 SHA-1
答案 11 :(得分:0)