我有一些看起来像这样的C#代码:

uint a = 0x9E3779B9;
a += (uint)(url[k + 0] + (url[k + 1] << 8) + (url[k + 2] << 16) + (url[k + 3] << 24));

在该代码之后,a == 228 452 386

现在,我正在尝试将此C#代码转换为PHP,但是在PHP中,数字并没有以相同的方式溢出:

$a = 0x9E3779B9;
$a += ($url[$k+0] + ($url[$k+1] << 8) + ($url[$k+2] << 16) + ($url[$k+3] << 24));

在该代码之后,$ a == 4 523 419 682

在两个COSE中,“ URL”被视为ASCII值的数组。返回相同的结果,直到将$ a添加到第二行的结果中为止。那时,C#UINT溢出到约2.28亿。 PHP变得“聪明”,并提出了“正确”的答案。

但是我想要C#给出的溢出答案。我该怎么办?

有帮助吗?

解决方案

添加一个 $a &= 0xFFFFFFFF 完成后,将值放回32位范围 +=.

(看: http://www.ideone.com/6br0u)

其他提示

已经有一段时间了,已经提交了一个工作答案,但是我只是想强调一种更简单的方法来执行您正在做的拆箱:

$a = 0x9e3779b9;
$url = 'info';

$a = ($a + current(unpack('L', $url))) & 0xffffffff;

printf("%u\n", $a); // 228452387

我正在使用 unpack() 要执行从二进制转换为UINT32(机器字节订单)。在32位平台上,最终结果可能会变成负面,这就是为什么我也使用 printf() 正确格式化结果。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top