我必须经常在格式为
的大型(最多1G)CSV数据库中搜索哈希值sha256_hash, md5_hash, sha1_hash, field1, field2, field3 etc
在C中。这需要非常快,内存使用不是问题(最低32G)。我发现this与我的想法非常接近:将数据加载到RAM中,通过哈希对数据库进行一次性排序,通过哈希的前“n”字节进行索引,然后搜索较小的子列表。但上面的帖子似乎并没有解决我在中期遇到的问题。由于我不是加密人,我想知道哈希的分布以及它是否可以用来更快地搜索子列表。关于这个或者我的一般方法的任何建议?
答案 0 :(得分:1)
是的,通过使用散列位的分布,可以使用布隆过滤器来提前确定“明确的否定”。
http://en.wikipedia.org/wiki/Bloom_filter
要为给定存储桶创建bloom过滤器,请将逻辑或所有哈希值合并在一起以创建过滤器。然后逻辑AND过滤器与您的目标哈希。如果结果是<您的目标哈希(或结果XOR目标哈希!= 0),该桶肯定不包含该目标哈希,您可以跳过搜索它,但如果结果==目标哈希,该桶可能包含您的目标哈希,并且您需要继续搜索才能确定。只需在添加新哈希时缓存和更新布隆过滤器,但在删除哈希时必须重新计算布隆过滤器,因此搜索剩下的所有内容都是AND和<操作非常便宜,并且在最佳情况下将O(N)操作减少到O(1)时间。
必须注意铲斗尺寸,以便产生有意义值的滤波器,因为所有高位滤波器对任何人都没有价值。
答案 1 :(得分:0)
这是一个非常容易解决的大量内存问题。使哈希成为哈希表的关键。将您提供给表的哈希值设置为哈希的前N个字节(因为它们是如此随机,以至于除了真正的随机数据之外,地球上没有任何人可以告诉它们。)
不确定你的想法是什么,用键的前缀键入表并有子列表。任何库存库提供的哈希表都可以轻松解决您的问题。
或者将其放入任何数据库并将哈希作为主键。
答案 2 :(得分:0)
哈希的分布是统一的,这很有用,因为你可以将哈希值放在哈希表中。
// something like this...
struct entry {
bool used;
unsigned char sha256[32];
char field1[20];
char field2[20];
};
如果您不需要从哈希表中删除条目,只需创建一个大数组struct entry
,并将CSV中的记录插入到与SHA-256哈希中的某些位对应的索引中。使用线性探测来插入条目:如果进入条目i
,请使用i+1
或i+2
,直到找到免费条目。
struct table {
int nbits;
struct entry *entries;
};
unsigned read_int(unsigned char *data)
{
unsigned v = data[0] | (data[1] << 8) |
(data[2] << 16) | ((unsigned)data[3] << 24);
}
struct entry *find_entry(struct table *table, unsigned char *sha256)
{
unsigned index = read_int(sha256);
unsigned mask = (1u << table->nbits) - 1;
while (1) {
struct entry *e = &table->entries[index & mask];
if (!e->used)
return NULL;
if (!memcmp(e->sha256, sha256, 32))
return e;
index++;
}
}