【问题标题】:Generating an integer hash-code for any PHP value为任何 PHP 值生成整数哈希码
【发布时间】:2014-11-11 07:39:26
【问题描述】:

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

  1. 对于对象$x$y 其中$x === $y, hashCode($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的替代方法...

【问题讨论】:

  • 用例是什么,如果你不介意我问的话?
  • 与数组相比,您处理对象的方式可能存在冲突。对象哈希是根据运行时的唯一对象 ID 创建的。为数组创建一个必须从其值派生。换句话说,两个相同的数组将具有相同的哈希值,而一个对象的 2 个克隆则不会。
  • @SverriM.Olsen - 我正在尝试为不可变映射实现一个 hash-array-mapped-trie(更多的是出于好奇而不是任何有用的东西,但如果它有用的话会很好。 ..!)
  • @Flosculus - 我知道这一点,这是预期的行为。一个对象的两个克隆也将无法通过=== 测试,所以我很高兴它们的哈希值会有所不同

标签: php hash hashcode


【解决方案1】:

这是我能找到的所有哈希选项。

适用于字符串,但也可以转换为数组/对象。

/**
 * 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");
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-05-12
    • 2014-05-11
    • 1970-01-01
    • 1970-01-01
    • 2014-11-14
    • 2014-12-31
    • 2021-05-14
    • 1970-01-01
    相关资源
    最近更新 更多