我在德尔福一个相当简单的函数,它接受一个字符串,并基于该字符串的散列整数德尔福按位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