String 通过哈希比较长字符串

String 通过哈希比较长字符串,string,hash,compare,String,Hash,Compare,为了提高比较字符串的函数的性能,我决定通过比较它们的散列来比较它们。 因此,如果两个非常长的字符串的哈希值彼此相等,那么字符串也彼此相等,这有保证吗?虽然可以保证两个相同的字符串将提供相等的哈希值,但另一种情况是不正确的:对于给定的哈希值,总是有几个可能的字符串产生相同的哈希值。 这是真实的,因为这是错误的 也就是说,两个不同的字符串产生相同哈希值的可能性可以是无穷小的,甚至被认为等于null 这种散列的一个相当经典的例子是,它具有近乎完美的128位分布。也就是说,在2^128中,有一次两个不同

为了提高比较字符串的函数的性能,我决定通过比较它们的散列来比较它们。
因此,如果两个非常长的字符串的哈希值彼此相等,那么字符串也彼此相等,这有保证吗?

虽然可以保证两个相同的字符串将提供相等的哈希值,但另一种情况是不正确的:对于给定的哈希值,总是有几个可能的字符串产生相同的哈希值。 这是真实的,因为这是错误的

也就是说,两个不同的字符串产生相同哈希值的可能性可以是无穷小的,甚至被认为等于null


这种散列的一个相当经典的例子是,它具有近乎完美的128位分布。也就是说,在2^128中,有一次两个不同的字符串生成相同的哈希。好吧,基本上,几乎和不可能一样。

我不确定你的表现是否会有所提高。两者:构建哈希+比较整数和简单地使用等于比较字符串具有相同的复杂性,即O(n),其中n是字符数。

在比较两个长字符串以确定它们是否相同的简单常见情况下,出于两个原因,简单比较比哈希更可取。首先,正如@wildplasser所指出的,散列需要遍历两个字符串的所有字节才能计算这两个散列值,而简单比较是快速的,只需要遍历字节,直到找到第一个差异,这可能远远小于整个字符串长度。其次,一个简单的比较可以保证检测到任何差异,而散列只给出它们完全相同的高概率,正如@AdamLiss和@Cyan所指出的

然而,在一些有趣的情况下,哈希比较可以发挥很大的优势。正如@Cyan所提到的,如果要多次进行比较,或者必须存储以供以后使用,那么散列可能会更快。其他人未提及的一种情况是,字符串位于通过本地网络或Internet连接的不同机器上。在两台机器之间传递少量数据通常要快得多。最简单的第一个检查是比较两个的大小,如果不同,就完成了。否则,计算散列,每个散列在自己的机器上(假设您能够在远程机器上创建进程),如果完成了不同的操作,则再次计算散列。如果散列值是相同的,并且必须具有绝对确定性,那么没有简单的捷径可以实现这种确定性。在两端使用无损压缩将允许传输更少的数据进行比较。最后,如果这两个字符串是按时间分开的,正如@Cyan所提到的,如果您想知道一个文件是否从昨天起发生了更改,并且您存储了昨天版本的哈希,那么您可以将今天的哈希与之进行比较


我希望这将有助于为某人激发一些“开箱即用”的想法。

我相信是这样。散列是它们包含的数据的绝对表示。所以相等的字符串应该有相等的散列。为什么不首先比较字符串呢。计算散列将迫使您检查两个字符串的每个字符。比较它们也是如此(但这可能会在第一次失配时返回“不相等”)@Jeremy1026:这根本不是真的。假设使用4位哈希。4位可以保存2^4=16个不同的值,因此您永远无法使用该散列来区分超过16个字符串。实际上,散列通常是数百位的,但它们能够区分的项目数量总是有限制的。诚然,使用足够长的散列,冲突极不可能发生,但无法保证不同的字符串将具有不同的散列。有趣的是,MD5已被破坏:攻击者可以故意创建一个散列到任何给定值的字符串。根本就没有足够的位,这就是为什么SHA已经成为当前密码学的标准。是的,这就是获得“随机碰撞”和获得“有意碰撞”之间的巨大区别。在随机方面,MD5仍然足够好。现在,如果系统必须考虑故意冲突的风险(这并不总是必要的),那么是的,MD5已经不够好了。生成和比较MD5哈希如何比比较原始字符串更快?!?它可能不会更快。事实上,这取决于用例。通常,如果只进行一次比较,那么直接比较原始字符串会更快。但是,如果必须对其进行多次比较(通常是寻找重复项),或者如果必须存储结果以供以后重新使用,则比较哈希会占上风。