【发布时间】:2021-12-07 01:27:44
【问题描述】:
我在 c 中实现了一个哈希表,我选择了我需要存储的文件的 sha256 哈希作为键。问题是我需要将键转换为可重用索引以插入哈希表。我很难重新散列密钥,但这样我会增加重叠值的可能性。有没有办法使用这个哈希作为表的键?
sha256 存储为 BYTE[32] 或可以转换为字符串
void* ht_get(ht* table, const char *key) {
size_t index = magicfunction(key);
while (table->entries[index].key != NULL) {
if (strcmp(key, table->entries[index].key) == 0) {
// Found key, return value.
return table->entries[index].value;
}
// Key wasn't in this slot, move to next (linear probing).
index++;
if (index >= table->capacity) {
index = 0;
}
}
return NULL;
}
【问题讨论】:
-
如果是 32 字节,则为 32 字节——无论它是什么类型,它都不能用作索引,因为您根本无法为按 32 字节索引的表提供足够的内存。您必须使用较小的尺寸,这会增加碰撞。不过,您不需要重新散列它,您可以简单地使用任意数量的字节。
-
除非您可以分配大小为 1e77 的表,否则您将不得不丢弃部分哈希,然后处理由此产生的哈希冲突。
-
由于
sha256被认为是一个很好的随机数生成器,我建议只使用前 8 个字节或size_t的大小。当然,之后不要忘记index %= table->capacity;。 -
您需要处理潜在的恶意数据吗?也就是说,您是否担心攻击者可能会选择您散列的数据,从而导致散列冲突并减少表的有效大小?如果您需要抵抗算法复杂性攻击,您可能需要使用随机方法来减少哈希空间。
-
@Cosinus 这将是一种方法。另一种方法是在“压缩”SHA256 哈希的过程中使用一些随机性。您可以使用 xxhash 之类的东西来压缩随机种子,然后是 SHA256 哈希。 (由于defend against algorithmic complexity attacks,这就是 XRP Ledger 的哈希表。)