我在Delphi中有一个相当简单的函数,它接受一个字符串并根据该字符串产生一个散列整数:
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&lt;&lt; 24为变量X生成与Delphi相同的值,但结果仍然不同。
我错过了一些非常明显的东西吗?
编辑: 这两个函数的输出是:
的Delphi
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
因此,直到字符“i”,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);
}
}
这现在有效!还要感谢Ignacio的面具理念:)
答案 0 :(得分:1)
掩盖你想要的位。
if ($X<>0){$Result = ($Result ^ ($X>>24)) & 0xFF;}
答案 1 :(得分:1)
你确定Delphi是对的,PHP是错的吗?
Delphi的shl和shr显然可以用签名整数表现不可预测。见:http://www.merlyn.demon.co.uk/del-bits.htm#SAR。斯托克顿博士似乎暗示有两种类型的移位操作:算术移位(保持符号)和逻辑移位。
文档(http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/expressions_xml.html)对shl / shr对有符号整数的影响不是很清楚。然而,他们确实提到shr / shl为1仅与无符号整数的divions /乘以2相当。
我无法找到Stockton博士(来自第一个链接)调用逻辑移位操作,但似乎合乎逻辑:-)尝试更改delphi实现以使用无符号8字节类型(DWORD来到(看)有什么影响。