[英]Is this the correct way of testing the avalanche effect of a hash function?
我正在尝试用 C 实现一个哈希表来丰富我对数据结构的理解。
有很多用于哈希表实现的哈希函数。
为了比较散列函数,有一个称为雪崩效应测试的测试。
为了测试我目前拥有的哈希函数集,我用 Java 编写了一个小程序:
public static void testHashAvalanche() {
Set<Long> collisionSet = new HashSet<>();
// The input for the hash function with 128 bytes.
byte[] bytes = new byte[128];
long count = 0;
long previous = 0;
long totalAvalanche = 0;
// Generate the inputs for hashing with a slight change of bit each time
for (int i = 0; i < 128; i++) {
// Byte value from 0 -> 255
for (int j = 0; j < 256; j++) {
long current = hash(bytes); // Any hash function with 64 bit output
int avalanche = calculateAvalanche(previous, current);
totalAvalanche += avalanche;
bytes[i]++;
count++;
previous = current;
}
}
System.out.println("Average Avalanche: " + (double) totalAvalanche / (double) count);
}
public static int calculateAvalanche(long a, long b) {
long difference = a ^ b;
return Long.bitCount(difference);
}
我想知道这是否是一种正确的方法,或者还有其他方法来测试散列函数。
谢谢!
让我们从快速观察开始。 假设您正在散列 128 字节的值。 这意味着您正在对 1024 位长的输入进行哈希处理。 有多少个不同的 1024 位数字? 嗯,第一位可以是零或一。 独立地,第二位可以是零或一。 与此无关,第三位可以是零或一等。这意味着这些位的可能组合数是 2 × 2 × ... × 2,总共 1024 次,或 2 1024 。
就上下文而言,这个数字是惊人的。 称其为“天文数字”实际上是对这个数字的侮辱,因为可观测宇宙中的原子数量大约为 2 300 。 您根本无法尝试所有 2 1024种输入组合以查看它们之间的差异。
那么你能做些什么呢? 一种选择是选择不同输入的样本,并为每个输入计算与它们有一点不同的所有数字。 然后,将所有这些散列,查看有多少输出位翻转,并将这些数字平均在一起。 另一种选择是选择一个随机值,在其中翻转一些位,计算输出散列的变化量,然后重复此过程以粗略估计散列在实践中的变化情况。 或者您可以在“真实”输入(可能来自数据库或某处的值列表)上使用这些方法,对输入进行“真实”编辑(对于某些定义,可能通过将一个值的哈希值与“相似”值的哈希值进行比较“类似”)。
您正在采取的方法是沿着这些路线的,但并不完全相同。 具体来说,您的方法通过维护一个字节数组来工作,循环浏览模式
0 0 0 0 ... 0 0
0 0 0 0 ... 0 1
0 0 0 0 ... 0 2
0 0 0 0 ... 0 3
0 0 0 0 ... 0 4
...
0 0 0 0 ... 1 0
0 0 0 0 ... 2 0
0 0 0 0 ... 3 0
0 0 0 0 ... 4 0
...
这有几个问题。 首先,这些输入可能不是可能输入的良好代表性样本。 (尽管在您的应用程序中散列这些类型的值可能很常见,在这种情况下您可以忽略这一点。^_^)
接下来的问题是,你改变一次一个字节,在一个时间,而不是一个位。 这可能是也可能不是问题,这取决于您要测量的内容。 如果您正在寻找单个字节级别的雪崩效应,这很好。 但是,如果您正在寻找单个位级别的雪崩效应,这将不起作用。 例如,将一个字节从 15 (00001111) 滚动到 16 (00010000) 会更改 5 位。 通过使用格雷码以一次翻转一位的方式循环遍历所有可能的字节,您可以保持当前一次修改一个字节的方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.