2012-01-10 42 views
5

我要寻找的PHP equelent Java的PHP内部的hashCode功能

"SomeString".hashCode(); 

功能。我正在寻找的hashCode应该与用于索引PHP中的HashMap相同。我希望你能帮助我:)

编辑:

好吧发现功能我正在寻找它的C语言编写的,而不是在PHP本身,而是感谢您的帮助可用!

ulong zend_inline_hash_func(char *arKey, uint nKeyLength) 
{ 
     ulong $h = 5381; 
     char *arEnd = arKey + nKeyLength; 

     while (arKey < arEnd) { 
       $h += ($h << 5); 
       $h += (ulong) *arKey++; 
     } 
     return $h; 
} 

回答

6

由guiguoz引用的Arkh和github解决方案是正确的方向,但都未能考虑到PHP将上转换整数散列只要超过2^61,价值就会翻番。使用固定硬件32位有符号值计算的java函数涉及32位算术溢出(CPU固有的),以将该值保留为32位有符号整数。

在PHP中,您将需要手动执行算术溢出每次$哈希更新时间:

function overflow32($v) 
{ 
    $v = $v % 4294967296; 
    if ($v > 2147483647) return $v - 4294967296; 
    elseif ($v < -2147483648) return $v + 4294967296; 
    else return $v; 
} 

function hashCode($s) 
{ 
    $h = 0; 
    $len = strlen($s); 
    for($i = 0; $i < $len; $i++) 
    { 
     $h = overflow32(31 * $h + ord($s[$i])); 
    } 

    return $h; 
} 

(编辑:更正%V错字)

+3

overflow32方法是错误的(%v而不是$ v,它在32位计算机上被0除)。 $ h =(int)(31 * $ h + ord($ s [$ i]))&0xffffffff;' – xryl669 2013-09-19 10:27:07

+0

@ xryl669,你的代码行会在'hashCode( “153193cc3139f12e”)'。它将返回3369976574而不是-924990722。 – ahoo 2015-07-15 15:21:25

+0

这仍然不适用于32位系统。 – SOFe 2016-02-22 11:05:46

3

在php中没有这样的方法可用。所以你将不得不实施正确的方法。 Wikipedia给出了Java.lang.hashCode使用的算法,该算法使用的字符串我想,所以这里是它的一个快速的PHP版本:

<?php 
function getStringHashCode($string){ 
    $hash = 0; 
    $stringLength = strlen($string); 
    for($i = 0; $i < $stringLength; $i++){ 
    $hash = 31 * $hash + $string[$i]; 
    } 
    return $hash; 
} 
+1

thx这段代码,但我需要完全相同的内部用于建设hashmaps。 – user982911 2012-01-10 15:41:48

+1

这个函数是错误的,https://gist.github.com/andreyknupp/5061911有一个正确的实现,但是如果字符串上有空格,它仍然会产生不同的哈希值。 – guigouz 2013-03-01 02:14:34

1

spl_object_hash可能是最接近你想要什么,但尽管命名它并不真正返回传入值的散列值,而只是一个内部唯一标识符。我不知道它是否真的用于阵列等实际使用的散列。

1

这里是我的执行2美分Java的hashCode返回PHP:

/** 
* Simulates java hashCode function 
* hash a string to 32 bit 
* @param str the string to hash 
* @return hashed 32 bit integer 
*/ 
function hashCode($str) { 
    $str = (string)$str; 
    $hash = 0; 
    $len = strlen($str); 
    if ($len == 0) 
     return $hash; 

    for ($i = 0; $i < $len; $i++) { 
     $h = $hash << 5; 
     $h -= $hash; 
     $h += ord($str[$i]); 
     $hash = $h; 
     $hash &= 0xFFFFFFFF; 
    } 
    return $hash; 
}; 
1

一个UTF-8版,表情符号支援

function str_hashcode($s){ 
    $hash = 0; 
    $len = mb_strlen($s, 'UTF-8'); 
    if($len == 0) 
     return $hash; 
    for ($i = 0; $i < $len; $i++) { 
     $c = mb_substr($s, $i, 1, 'UTF-8'); 
     $cc = unpack('V', iconv('UTF-8', 'UCS-4LE', $c))[1]; 
     $hash = (($hash << 5) - $hash) + $cc; 
     $hash &= $hash; // 16bit > 32bit 
    } 
    return $hash; 
}