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