用于对数组进行指纹识别的最快方法(从数据数组计算唯一哈希)

时间:2012-03-21 21:33:02

标签: php arrays hash fingerprint

我在WWW Framework中使用了大量的缓存和缓冲API调用,我最终使用的一个东西是“指纹识别”数据,以匹配缓存文件名以及检测具有的API调用已经做好了。

许多数据都在数组中移动,如GET,POST等。因此,API调用的唯一性取决于数据。

因此,我需要指纹这些信息。要做到这一点,还需要从数据数组生成一个“指纹”,并将其散列到一个我可以存储和比较的字符串中。

对于数组序列化,PHP中有serialize()和json_encode()。在各种基准测试之后,我认为json_encode()是一种更快的序列化数组的方法,我对它非常满意。

对于散列,有md5()和sha1()函数,根据我的基准测试,md5()的速度更快。

所以我目前的指纹算法是:

$fingerprint=md5(json_encode($array));

但我怀疑这是否是用于在PHP中对数组进行指纹识别的“最快可能”方法。我曾尝试使用Google和StackOverflow,但没有找到好的替代品。我是在正确的轨道还是我需要做一些不同的事情?

3 个答案:

答案 0 :(得分:4)

一旦你得到了数组json_encoded,如果你主要关注速度,你应该使用非cyrptographic哈希函数。不同的哈希函数适用于不同的东西。 MD5和Sha1被称为加密,因为它们难以逆转(请注意,由于漏洞,它们被广泛认为是出于安全目的而被弃用)。 CRC(循环冗余校验)功能是错误检测代码,无论如何都不适合于唯一性。

维基百科是一个很好的起点,只是因为那里的贡献通常有外部链接到库实现:List of hash functions。我建议阅读那里的一些非加密库并对它们进行基准测试。非加密函数更多是针对速度和合理的唯一性程度而编写的,牺牲了安全性,错误检测和其他有趣的属性,这些属性正是您所描述的。

如果您主要关注速度,最后需要注意的是如何存储和比较指纹本身。 MD5输出128位数据,如果没有额外的库调用和开销,它将不适合php中的数字类型。对于我的钱,我敢打赌,你可以获得最佳的比较速度,存储将来自一个可以直接输出64位数字的哈希函数。请注意,要在php中本地获取64个数字,您需要拥有64位硬件并在64位模式下配置/安装php。我在这里的某些地方有一些代码,我曾用它来测试我们可能在我感兴趣时可以挖掘的阶段和生产环境。

顺便说一下,我认为你不会得到比json-encode更快的数组字符串化。这个问题的核心是数组行走和字符串操作,因此速度基本上与输出的详细程度成正比。与php的序列化或导出函数相比,JSON编码非常简洁。我敢打赌,如果你在php文档页面上查看了足够多的评论,你会发现有人编写了一个直接将数组作为输入的哈希函数,但是它是否是任何好的都是赌博。

如果我不清楚任何事情,请随时提问。

答案 1 :(得分:1)

我认为@Patrick M解释非常好,我只是想在这里添加一些额外的数据。

正如@Patrick M所说,md5是一个加密哈希,它将为增加安全性做出一些额外的努力(即使现在已经为此目的而弃用)。

您可以使用hash功能查看可用的hash_algos个功能。

但是,在这里你可以看到一个benchmark of those algorithms,它说(我没有尝试过自己),md4越快,md5等等。< / p>

公平地说,基准测试应该使用特定功能(如果有的话),以确保(md5sha1crc32,...),因为它可能更快(或更慢,谁知道)。

总之,我认为你的方法看起来很不错。

请注意,md5并不安全,正如PHP's Password Hashing FAQ中所描述的那样,所以如果您需要存储信用卡指纹或某种类型的东西(我不会# 39;认为这是你的情况),你可能需要另外一个功能以及增加一些额外的步骤。

作为替代方案,您可以查看spl_object_hash

答案 2 :(得分:0)

我在100个循环中对7000个阵列进行了测试,最快的速度是crc32(serialize($arr))(平均0.65秒)

    $arr = ['name' => $name, 'category' => $category, 'hits' => $hits];

    md5(var_export($arr, true));
    md5(serialize($arr));
    md5(json_encode($arr));

    hash('md5', var_export($arr, true), "");
    hash('md5', serialize($arr), "");
    hash('md5', json_encode($arr), "");

    hash('md4', var_export($arr, true), "");
    hash('md4', serialize($arr), "");
    hash('md4', json_encode($arr), "");

    crc32(var_export($arr, true));
    crc32(serialize($arr));
    crc32(json_encode($arr));

    sha1(var_export($arr, true));
    sha1(serialize($arr));
    sha1(json_encode($arr));

    spl_object_hash((object) $arr);