为任何PHP值生成一个整数哈希代码



我正在寻找一种方法,在PHP中,为任何值基元类型或用户定义的类(对于类似trie的结构)生成整数哈希代码。此哈希应该具有以下属性:

  1. 对于对象$x$y,其中$x === $yhashCode($x) === hashCode($y)
  2. 返回32位值
  3. 理想情况下,散列函数应该分布良好(即不会有太多冲突)
  4. 尽可能快(无需编写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");
    }
}

最新更新