我正在寻找一种方法,在PHP中,为任何值基元类型或用户定义的类(对于类似trie的结构)生成整数哈希代码。此哈希应该具有以下属性:
- 对于对象
$x
和$y
,其中$x === $y
、hashCode($x) === hashCode($y)
- 返回32位值
- 理想情况下,散列函数应该分布良好(即不会有太多冲突)
- 尽可能快(无需编写C扩展)
我能想到的最好的方法是获得一个字符串哈希并将其转换为整数:
<?php
function hashCode($o) {
// Get a string hash for the value
if( is_object($o) ) {
// For objects, use spl_object_hash
$strHash = spl_object_hash($o);
}
else {
// Now we know we have a primitive type
// For arrays, first hash the contents
if( is_array($o) )
$o = array_map(function($x) { return hashCode($x); }, $o);
// Use serialisation to get a string for the primitive
// NOTE: We could use casting to a string since, however this will
// lead to more collisions since, for instance,
// (string)true === '1'
// Also, casting a float to a string causes it to lose precision,
// meaning more collisions
// Maybe this is OK though...
// We use md5 to reduce the size (think serialising a large string)
$strHash = md5(serialize($o));
}
// Convert the string hash to a 32-bit integer
return crc32($strHash);
}
只是想知道是否有人有其他想法?对我来说,数组哈希似乎特别复杂,而且可能很慢。此外,我忍不住想,我缺少了一个直接求整数的方法,或者serialize
/md5
/crc32
的替代方法。。。
这是我能找到的所有哈希选项。
适用于字符串,但也可以转换为数组/对象。
/**
* Make a control key with the string containing datas
*
* @param string $data Data
* @param string $controlType Type of control 'md5', 'crc32' or 'strlen'
* @throws Zend_Cache_Exception
* @return string Control key
*/
protected function _hash($data, $controlType)
{
switch ($controlType) {
case 'md5':
return md5($data);
case 'crc32':
return crc32($data);
case 'strlen':
return strlen($data);
case 'adler32':
return hash('adler32', $data);
default:
Zend_Cache::throwException("Incorrect hash function : $controlType");
}
}