我在德爾福一個相當簡單的函數,它接受一個字符串,並基於該字符串的散列整數德爾福按位PROC轉換到PHP
function TfrmMain.HashElf(const Buf; BufSize : LongInt) : LongInt;
var
Bytes : TByteArray absolute Buf;
I, X : LongInt;
begin
Result := 0;
for I := 0 to BufSize - 1 do begin
Result := (Result shl 4) + Bytes[I];
X := Result and $F0000000;
if (X <> 0) then Result := Result xor (X shr 24);
Result := Result and (not X);
end;
end;
我將其轉換爲PHP,但結果並不一樣。這是我在PHP中已經有了:
function HashElf($Buf, $BufSize){
$Bytes = str_split($Buf);
for ($i= 0; $i<$BufSize;$i++){
$Result = ($Result << 4) + Ord($Bytes[$i]);
$X = $Result & (0xF0000000);
if ($X<>0){$Result = $Result^($X>>24);}
$Result = ($Result & (~ $X));
}
return $Result;
}
如果在字符串的TestString到Delphi函數傳遞你195831015但是PHP返回72559895.我注意到的差異後,才7個字符變得明顯。如果測試字符串只是測試結果是相同的。
PHP似乎有一些困難負整數右移例如如下因素行:
if ($X<>0){$Result = $Result^($X>>24);}
改變爲左移$ X < < 24產生如Delphi的相同的值的變量X ,但結果仍然不同。
我在這裏錯過了一些非常明顯的東西嗎?
編輯: 的兩個函數的輸出是:
德爾福
Char: t Result: 116 X: 0
Char: e Result: 1957 X: 0
Char: s Result: 31427 X: 0
Char: t Result: 502948 X: 0
Char: s Result: 8047283 X: 0
Char: t Result: 128756644 X: 0
Char: r Result: 181058242 X: 1879048192
Char: i Result: 212577321 X: -1610612736
Char: n Result: 180011582 X: -1073741824
Char: g Result: 195831015 X: -1610612736
PHP
Char: t $Result: 116 $X: 0
Char: e $Result: 1957 $X: 0
Char: s $Result: 31427 $X: 0
Char: t $Result: 502948 $X: 0
Char: s $Result: 8047283 $X: 0
Char: t $Result: 128756644 $X: 0
Char: r $Result: 181058242 $X: 1879048192
Char: i $Result: 212577417 $X: -1610612736
Char: n $Result: 180013310 $X: -1073741824
Char: g $Result: 195858503 $X: -1610612736
所以它不是直到字符 「我」 在PHP開始跑題與計算
EDIT2:
加入PHP函數做邏輯右移,而不是算術移位的:
function lshiftright($var,$amt)
{
$mask = 0x40000000;
if($var < 0)
{
$var &= 0x7FFFFFFF;
$mask = $mask >> ($amt-1);
return ($var >> $amt) | $mask;
}else{
return ($var >> $amt);
}
}
這就是現在的作品!也感謝伊格納西奧面具的想法:)
感謝您的提示 - 再次檢查PHP手冊,推測該位移僅爲算術。我在Delphi中使用了額外的位掩碼,但是後來我發現強制PHP執行我想要的操作會更好 - 請參閱編輯其他代碼 – Rucia