2012-01-10 43 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; 
}