Вопрос

У меня есть код 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

В обоих COSS «URL» рассматривается как множество значений ASCII. Возвращает те же результаты до того момента, когда $ A не будет добавлен в результат второй строки. В этот момент C# Uint переполняется до ~ 228 миллионов. 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