Обход ограничений РНР
Итак - в данный момент пишу подключение через сокеты к удаленному игровому серверу. С сокетами проблем не было, приступил к реализации шифрования. Выдали мне несколько файлов с С++ кодом - и вперед переписывать на РНР. Переписал - не работает. Тестовую строку не расшифровывает. Проверил разок - не работает. Проверил построчно (мало ли пропустил что-то) - не работает. 4 часа времени, 100 тыс нервных клеток - и решение найдено.
Вот кусок сишного кода:
Код:
unLo ^= sbox1[(int)(unHi >> 24)];
Переменная unHi имеет тип данных unsigned int (целое беззнаковое, 32 бита). Хитрость состоит в том, что в РНР нет такого типа данных. Все целые числа имеют тип int (целое со знаком, 32 бита). Соответственно операция побитового сдвига (unHi >> 24) в С++ возвращала результат (допустим) 0х0000008С, а в РНР такая же операция возвращала 0хFFFFFF8C.
Лечится достаточно просто (хотя в моем случае пришлось перелопатить немало кода) - вместо
Код:
$unLo ^= $sbox1[(int)($unHi >> 24)];
надо писать
Код:
$unLo ^= $sbox1[(int)(($unHi >> 24) & 0xFF)];
И все становится правильно. Может кому пригодится.:)
PS Кстати яркий пример того, что в порой требуется иметь возможность жестко указать тип данных. Будем надеятся что в РНР 6 помимо namespace и перегрузки функций и операторов появится такая возможность.