2014-03-13 53 views
0

對於Web應用程序,我需要PHP中的RSHash函數(RSHash => Robert Sedgewick的字符串散列算法)。如何爲PHP創建RSHash函數

我確實在VB6中有一個實現,我現在必須在PHP中重建這個函數。我所擁有的是以下VB6碼:

Private Function RSHash(ByVal Str As String) As Double 
    Dim b As Long 
    Dim a As Variant 
    Dim hash As Variant 
    Dim i As Long 
    b = 378551 
    a = 63689 
    For i = 1 To Len(Str) 
     hash = MultiLong(hash, a) + Asc(Mid(Str, i, 1)) 
     a = MultiLong(a, b) 
    Next i 
    RSHash = hash 
End Function 

Private Function MultiLong(a As Variant, b As Variant) As Variant 
    Dim vDec As Variant 
    vDec = CDec(a) 
    vDec = CDec(a) * CDec(b) 
    vDec = vDec - CDec(Fix(vDec/(2^32))) * CDec((2^32)) 
    MultiLong = vDec 
End Function 

我在PHP做了:

function RSHash($string) { 
    $a = 63689; 
    $b = 378551; 
    $hash = 0; 

    for ($i = 0, $x = strlen($string); $i < $x; $i++) { 
     $hash = multiLong($hash, $a) + (int) ord($string[$i]); 
     $a = multiLong($a, $b); 
    } 

    return $hash; 
} 

function multiLong($a, $b) { 
    $x = $a * $b; 
    $y = floor($a * $b/pow(2,32)); 
    return $x - $y * pow(2,32); 
} 

但在PHP(5.2.17)的結果是不一樣的VB6。我認爲這是由於一些舍入錯誤。我還在函數「multilong」中測試了一些其他舍入函數,也不使用它。

在PHP中有什麼實現RSHash算法(我發現一些在許多其他語言,但不是PHP)? 如果沒有(也許這是不可能的),有沒有人有關於如何處理這個問題的建議?

在此先感謝!

解決方案:我們創建了一個計算哈希值的VB.net控制檯應用程序。這個exe是從PHP調用來獲得正確的。 看來,這是不可能的這個哈希算法轉換成PHP。

回答

1

看起來好像MultiLong()函數是在這裏指責的。我會盡量讓自己看起來是一樣的:

' Removing the first executable line of this function: 
' 
Private Function MultiLong(a As Variant, b As Variant) As Variant 
    Dim vDec As Variant 
    vDec = CDec(a) * CDec(b) 
    vDec = vDec - CDec(Fix(vDec/(2^32))) * CDec((2^32)) 
    MultiLong = vDec 
End Function 


function multiLong($a, $b) { 
    $vDec = $a * $b 
    $vDec = $vDec - (floor($vDec/pow(2,32)) * pow(2,32) 
    return $vDec 
} 

這與你的功能相比,它看起來好像問題是運算符優先級的一個:劃分優先乘,如

你做到:

floor($a * $b/pow(2, 32)) 

這可能會給從略有不同的結果:

floor(($a * $b)/pow(2, 32)) 
+0

我相信,那樓( $ a * $ b/pow(2,32))與floor(($ a * $ b)/ pow(2,32))相同,但我也嘗試了您的解決方案......它與VB6代碼。對於字符串「你好」的VB6代碼給出了987012754和PHP代碼1018443887 ...我仍然考慮因PHP/int中float/float的範圍而導致的舍入錯誤。我可以正確的使用它嗎? – mindhead

0

對我來說,下面的代碼工作:

function RSHash($string) { 
    $a = 63689; 
    $b = 378551; 
    $hash = 0; 

    for ($i = 0, $x = strlen($string); $i < $x; $i++) { 
     $hash = $hash * $a + (int) ord($string[$i]); 
     $hash = $hash % 65535; 
     $a = $a * $b; 
     $a = $a % 65535; 
    } 

    return $hash; 
}