Php 非常快速的哈希函数,用于哈希8-16字节字符串
我需要一个非常快速的字符串哈希函数,它非常适合用PHP编写的web应用程序 我试图克服的问题是在访问控制系统中为权限分配ID。我正在考虑使用哈希字符串来表示权限ID。通过这种方式,我可以像这样检查权限:Php 非常快速的哈希函数,用于哈希8-16字节字符串,php,string,hash,permissions,access-control,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")) { //
if ($Auth->isAllowed($user, "blog.comment")) {
// Do some operation
}
...
if ($Auth->isAllowed($user, "profile.avatar.change")) {
// Do some other operation
}
DB表将权限哈希映射到用户角色。要检查是否允许用户执行“profile.avatar.change”,将对相应的字符串进行哈希运算,并根据DB表进行检查
这非常方便,不需要担心在不同模块之间维护唯一的权限ID。但是散列函数应该非常有效。首先,他为什么不使用一个简单的md5
函数呢
试图自己编写散列
其中一个是一个简单的hashBernstein函数,也被称为乘以33加上
。zend在php
中使用它。在php
中,它可以实现如下:
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");
我的结果是:
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
结果在不同的执行过程中略有变化——前8个算法由于其接近的速度和对服务器负载的依赖性而处于混乱状态
应该选择什么?
您可以使用上面的前8个函数中的任意一个:$hash=hash('crc32',$string)代码>。实际上,一个广泛使用的md5
函数只比leader慢1.7倍
奖金
,但它们比crc32快4倍。在大多数情况下,哈希函数的处理时间可以忽略不计。
如果需要一些散列(8个字符),只需使用crc32函数即可
<?php
$hash = hash('crc32', 'WhatDoYouWant');
?>
您还可以将散列与uniqid组合以创建随机散列
<?php
$hash = hash('crc32', uniqid());
?>
使用。PrestoDB也使用它。散列上的PHP实现是单向的,所以对于类似的事情,除了它的存在之外,没有什么可以检查散列。最常见的方法是遵循linux方法。(使用0-7表示权限)。将ID分配给权限并执行2^(ID编号)以创建一个整数,然后以相同的方式展开它以确定您拥有哪些权限。。。或者只需传递带有一组变量的对象/令牌,然后检查$user->can\u change\u stuff或$user->has_apples@apokryfos,它不是复制品。这些都是我的问题。这个问题是关于字符串哈希的更具体的问题。@JayBlanchard,这正是我要检查的——数据库表中是否存在某个特定权限。将8-16字节字符串哈希为唯一字符串的最快方法是不对其执行任何操作。就按原样保存吧。虽然它很短。
<?php
$hash = hash('crc32', uniqid());
?>