【发布时间】:2010-10-19 05:38:28
【问题描述】:
假设我有一个 5000 个字符的文本块。我通过一个散列程序运行它并生成一个 40 字符长的散列。现在我运行另一个文本块,10000 个字符。它仍然会生成一个 40 个字符长的哈希值。对于任何长度的文本都是如此。
我的问题是,如果哈希都是唯一的,我不能将任何东西压缩成 40 个字符的字符串吗?
【问题讨论】:
标签: hash
假设我有一个 5000 个字符的文本块。我通过一个散列程序运行它并生成一个 40 字符长的散列。现在我运行另一个文本块,10000 个字符。它仍然会生成一个 40 个字符长的哈希值。对于任何长度的文本都是如此。
我的问题是,如果哈希都是唯一的,我不能将任何东西压缩成 40 个字符的字符串吗?
【问题讨论】:
标签: hash
散列不是唯一的。
散列是一种尝试为输入给它的每个值生成唯一散列的技术,但不能保证它是唯一的。
好的散列算法比差的散列算法出现重复散列值的频率要低得多。此外,散列是一个方向性的 - 这意味着你不能从散列 -> 原始,所以它不意味着压缩。
并且:哈希不需要是唯一的。相同的输入需要通过算法转换成相同的哈希。您不使用哈希作为标识符!
【讨论】:
并非所有哈希都保证是唯一的。关于该主题的维基百科条目非常好:http://en.wikipedia.org/wiki/Hash_function
【讨论】:
考虑哈希的一种方式类似于人类指纹(哈希有时也称为指纹)..
您可以将任何人“压缩”成(几乎)唯一的指纹。但是,仅凭指纹您无法知道某人是谁。这就像哈希一样,您可以轻松计算出@ 987654327@,但只给了a1b2c3,你不能随便告诉源数据。
要反转指纹,您需要将指纹与已知people->finger-prints的数据库进行比较(如果未知指纹与Person1匹配,则未知指纹属于他们)
使用散列,你必须做同样的事情——你有一个包含所有字符串->散列映射的数据库(称为rainbow table)。然后你用散列“a1b2c3”查找行,它显示“abcdef”是为了得到这个而散列的。另一种更常见的方法是简单地尝试每个字符组合,将它们散列并比较(brute force attack)
最后,虽然人类指纹是“唯一的”,但也有可能有两个相同的指纹,但这种可能性极小——哈希算法也是如此……一些哈希算法比其他算法更容易受到collisions 的影响。
我的问题是,如果哈希都是唯一的,我不能将任何东西压缩成 40 个字符的字符串吗?
理论上,散列是一种很好的压缩方法,但解压缩超出(比如说)10 个 ASCII 字符的数据是非常不切实际的。你是对的,你可以将任何内容压缩为 40 个字符的字符串,但实际上你不能解压缩它(甚至理论上也有点牵强..)
【讨论】:
echo blah > file1.txt; echo blah > file2.txt 并且两者都将具有相同的哈希...我不认为@bzxcv17 是在询问哈希冲突,而是 git 如何处理具有相同内容的多个文件( Pro Git link answers nicely)。据我所知,Git 忽略了哈希冲突的可能性(没有理智的方法来处理它,而且正如你所说,这极不可能 - 所以不是问题)
RSA 哈希不是唯一的。当散列两个不同的明文位时,您会产生误报的可能性非常小(大约为 1:36^40)。对于大多数应用程序来说,这种可能性被认为足够小,您可以忽略它,因为平均而言,发生意外碰撞需要数百万年的时间。
【讨论】:
散列是为了尽可能地传播,而不是为了唯一性!
当然,达到唯一性是达到 100% 传播, 但这通常是不可能的,不管你的哈希算法有多好。
引人注目的例子:
例如,C# 为每个对象提供一个 Int32 代码作为 HashCode... 对于 Int64 也是如此:
Int64 a = Int64.MaxValue;
Int32 myHash = a.GetHashCode();
这里的结论:Int64 有 2^64 个不同的可能实例,但它们只有 2^32 个哈希码!!
所以:Int64 的每个哈希值由(平均)共享
4 294 967 295
其他 Int64 的!
这么多独特性嘿:-)
【讨论】:
考虑从Pigeonhole Principle 的角度来看这个。如果您将 n 个项目填充到较少数量的桶 k 中,则必然会有一些包含多个项目的桶。因此,要回答您的问题,没有哈希值不是唯一的。
【讨论】:
哈希不保证是唯一的,但如果您正在寻找唯一的哈希,请查看gperf。它可以为一组预先确定的输入生成一个唯一的散列函数。
【讨论】:
您可以将任何文本的签名压缩为哈希,但您无法反向计算文本是什么给您该哈希。简单地说,找出给你散列的文本是什么的唯一方法是通过散列暴力破解文本以尝试找到匹配项。
【讨论】:
不要对 .Net GetHashCode() 感到困惑。这不是很好,因为它只有 32 位,而原始问题中的 640 位(如果每个字符都是 8 位)。
【讨论】:
如果您正确使用定义明确的哈希函数,您实际上可以假设哈希结果是唯一的。
问题,您的问题是哈希是单向函数。没有反函数可以取值并返回到原始 blob。除非您保留所有可能的原始值的巨大表(所谓的rainbow table)。
【讨论】:
它们不是唯一的,但是在找到两个具有相同哈希值的高质量算法的不同文档之前,您更有可能死于心脏病发作,例如SHA-1
【讨论】:
【讨论】: