在20字节数据上CRC16冲突的可能性是多少?

时间:2012-12-22 00:35:30

标签: security hash crc16

我正在开发一个系统,需要为20字节可能更短的结构存储散列。但是,为了优化在一系列哈希中查找哈希的过程,我们希望尽可能地减小哈希的大小。

所以我的问题是,我们提供给crc16哈希的数据量与它与相同长度的另一个条目冲突的概率之间是否存在关系?如果是这样,哪个是最佳长度?

18个字节属于ascii表(a-z,0-9),其余范围介于0到10之间

4 个答案:

答案 0 :(得分:3)

对于两个不同的输入,一个好的16位散列应该有2 ^ -16的碰撞概率。 CRC16不是一个非常好的哈希,但除非你有一个对手选择输入,它应该足够好用于你的目的。

请记住birthday paradox。在散列约2 ^ 8个项目后,您将开始发生冲突。

答案 1 :(得分:3)

以下简单脚本运行无限循环,获取2个随机20字节序列,计算CRC16并检查是否存在冲突。对此循环的持续评估事实上估计了碰撞百分比:

#!/usr/bin/env perl

use Digest::CRC qw(crc16);

open(my $f, '<', '/dev/urandom');
my $n = 0;
my $coll = 0;

while (1) {
    read $f, $randstr1, 20;
    read $f, $randstr2, 20;
    my $crc1 = crc16($randstr1);
    my $crc2 = crc16($randstr2);

    $n++;
    $coll++ if $crc1 == $crc2;

    printf "percent of collisions = %.6f%%\n", $coll * 100.0 / $n if ($n % 100000 == 0);
}

从我在计算机上看到的情况来看,碰撞百分比似乎在0.0016%(或1e-5或“100_000中的1”)附近,这比更糟预测估计基于16位散列的理想散列分布(例如2 ^ 16/2 ^ 160)。

更新:我看到你已经澄清了20个字节不仅仅是完全随机的字节,而是落入[a-z0-9]的范围内。以下是估算该字母表中冲突的更新版本:

#!/usr/bin/env perl

use Digest::CRC qw(crc16);

my $n = 0;
my $coll = 0;
my @chars = ('a'..'z', '0'..'9');

sub randstr() {
    my $res;
    foreach (1..20) { $res .= $chars[rand @chars]; }
    return $res;
}

while (1) {
    my $crc1 = crc16(randstr());
    my $crc2 = crc16(randstr());

    $n++;
    $coll++ if $crc1 == $crc2;

    printf "percent of collisions = %.4f%%\n", $coll * 100.0 / $n if ($n % 100000 == 0);
}

它产生的结果大致相同,约为0.0016%

答案 2 :(得分:2)

是否得到可能的哈希冲突取决于数据的内容,而不是数量。如果不是故意选择碰撞,那么在这种情况下你应该非常安全,其中数据的大小是散列大小的10倍。也就是说,它仍然是一个16位散列,现代标准中碰撞的可能性非常高。

答案 3 :(得分:0)

散列冲突的概率不依赖于消息的长度,只要消息的熵(有效位数)大于或等于散列中的位数,并且它是一个很好的哈希,可以很好地将输入的位混合到每个哈希中。

在你的情况下你有大约100比特的熵,所以只要你有一个长度为100比特或更短的好散列,那么碰撞概率将仅取决于散列中的比特数和机会数你有碰撞。 This answer显示了如何计算碰撞的概率。