用于散列8-16字节字符串的非常快速的散列函数

时间:2017-02-06 17:02:31

标签: php string hash permissions access-control

我需要一个非常快速的字符串散列函数,它非常适合用PHP编写的Web应用程序。

我想要克服的问题是为访问控制系统中的权限分配ID。我正在考虑使用散列字符串来表示权限ID。这样我就可以像这样检查权限:

if ($Auth->isAllowed($user, "blog.comment")) {
    // Do some operation
}
...

if ($Auth->isAllowed($user, "profile.avatar.change")) {
    // Do some other operation
}

数据库表会将权限哈希映射到用户的角色。检查用户是否被允许做" profile.avatar.change"相应的字符串将被散列并检查数据库表。

这非常方便,无需担心在不同模块之间维护唯一权限ID。但散列函数应该非常有效。

2 个答案:

答案 0 :(得分:12)

第一个是为什么他不使用简单的<div id="content"> <h2>Your profile</h2> <table id="profileTable"> <tr> <th>Username:</th> <td>CONTENT</td> </tr> <tr> <th>First name:</th> <td>CONTENT</td> </tr> </table> </div>函数?

尝试自己编写哈希

其中一个most frequently referred function是一个简单的散列 Bernstein函数,也称为md5。它由Times 33 with Addition由zend to make hashes for keys of associative array使用。在php中,可以按如下方式实施:

php

问题是当它以这种方式实现时,它相当慢。测试表明它比<{1}}慢〜3倍。所以我们必须找到最快的internal implementation of a hash function

查找最佳内部哈希

只需占用所有算法并测量时间来散列数百万字符串。

function djb2($s){
    $word = str_split($s);
    $length = count($word);

    $hashAddress = 5381;
    for ($counter = 0; $counter < $length; $counter++){
        $hashAddress = (($hashAddress << 5) + $hashAddress) + $word[$counter];
    }
    return $hashAddress;
}
echo djb2("stackoverflow");

我的结果是:

md5

结果从执行到执行稍有变化 - 前8个算法因为它们的速度接近以及它对服务器负载的依赖而进行了混乱。

应该选择什么?

您可以使用上面的前8个功能中的任何一个:function testing($algo, $str) { $start = microtime(true); for($ax = 0; $ax < 1000000; $ax++){ hash($algo, $str); } $end = microtime(true); return ($end - $start); } $algos = hash_algos(); $times = []; foreach($algos as $algo){ $times[$algo] = testing($algo, "stackoverflow"); } // sort by time ASC asort($times); foreach($times as $algo => $time){ echo "$algo -> " . round($time, 2)."sec\n"; } 。实际上,广泛使用的fnv1a32 -> 0.29sec fnv132 -> 0.3sec crc32b -> 0.3sec adler32 -> 0.3sec crc32 -> 0.31sec joaat -> 0.31sec fnv1a64 -> 0.31sec fnv164 -> 0.31sec md4 -> 0.46sec md5 -> 0.54sec ... md2 -> 6.32sec 函数只比领导者慢1.7倍。

<强>加成

There are another functions like SuperFastHash,未在$hash = hash('crc32', $string);代码中实施,但速度比md5快4倍。

答案 1 :(得分:2)

在大多数情况下,散列函数的处理时间可以忽略不计。 如果你需要一点哈希(8个字符),你可以简单地使用crc32函数。

<?php
$hash = hash('crc32', 'WhatDoYouWant');
?>

您还可以将hash与uniqid组合以创建随机哈希。

<?php
$hash = hash('crc32', uniqid());
?>