操纵SHA256哈希值非常大的文本数据库的最有效方法是什么?

时间:2014-06-06 17:54:04

标签: c database hash lookup

我必须经常在格式为

的大型(最多1G)CSV数据库中搜索哈希值
sha256_hash, md5_hash, sha1_hash, field1, field2, field3 etc
在C中

。这需要非常快,内存使用不是问题(最低32G)。我发现this与我的想法非常接近:将数据加载到RAM中,通过哈希对数据库进行一次性排序,通过哈希的前“n”字节进行索引,然后搜索较小的子列表。但上面的帖子似乎并没有解决我在中期遇到的问题。由于我不是加密人,我想知道哈希的分布以及它是否可以用来更快地搜索子列表。关于这个或者我的一般方法的任何建议?

3 个答案:

答案 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+1i+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++;
    }
}
相关问题