Функция ord,chr из php, как реализовать?

Подскажите пожалуйста.
Есть код, распаковки пакета написанный на php.
И строчка:
$part[$i] = chr(ord($part[$i]) ^ ord($zBytes[$i]));

Я перенес код в js, но есть момент.

В php ord('Ф') вернет 208, в js результат будет иным - 1060.
В js 'Ф'.charCodeAt(0)
из за этого результат распаковки пакета будет неверным.

Почему идет такое поведение и как это исправить/решить?

весь исходный код php:
function UnMunge($packet) {
    $MungeTable2 = array(0x05, 0x61, 0x7A, 0xED, 0x1B, 0xCA, 0x0D, 0x9B, 0x4A, 0xF1, 0x64, 0xC7, 0xB5, 0x8E, 0xDF, 0xA0);
    $z = ord($packet[0]);
    $packet = substr($packet, 8);
    $length = strlen($packet);
    $res = "";
    $count = 0;
    if ($length < 1) {
        return null;
    }

    $notz = ~$z;
    $length = $length >> 2;
    $zBytes = pack("L", $z);
    $notzBytes = pack("L", $notz);
    $x = 0;
    while ($length--) {
        $part = substr($packet, $count * 4, 4);
        for ($i = 0; $i < 4; $i++) {
            $part[$i] = chr(ord($part[$i]) ^ ord($zBytes[$i]));
        }

        for ($i = 0; $i < 4; $i++) {
            $part[$i] = chr(ord($part[$i]) ^ ((($MungeTable2[($count + $i) & 0x0F] | ($i << $i)) | $i) | 0xA5));
        }

        $s = "0000";
        for ($i = 0, $i2 = 3; $i < 4; $i++, $i2--) {
            $s[$i] = chr(ord($part[$i2]) ^ ord($notzBytes[$i]));
        }
        $res .= $s;
        $count++;
    }
    return $res;
}
$a = '010000c0010000805a18010051001041032a40016001014124660f377e3933737948106f908fd021c1b8c0812ba8c0f3a5c8f4919b99d1d0f48083908120e091d1d881be8becc0b48a99d1bfcbb0c0c3d1ab90b3c2fdc0f4411a71ca';
$a = hex2bin($a);
var_dump(UnMunge($a));
string(84) "J:Asv_version* Права доступа предоставлены! "
  • Вопрос задан
  • 599 просмотров
Решения вопроса 1
miraage
@miraage
Старый прогер
String.fromCharCode
String.prototype.charCodeAt
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Stalker_RED
@Stalker_RED
Возможно вы слышали, есть такая штука как кодировки текста, и все чаще используется UTF-8, который многобайтная кодировка.
А ord() - функция для работы с однобайтными.
function showOrd($char) {
	echo "\"$char\""
	. ' ord='.ord($char)
	. ' mb_ord='.mb_ord($char)
	. PHP_EOL;
}

showOrd('а'); // "а" ord=208 mb_ord=1072
showOrd('ф'); // "ф" ord=209 mb_ord=1092
showOrd('я'); // "я" ord=209 mb_ord=1103


Буква 'Ф' в utf-8 представлены двумя байтами, а не одним, и если вы примените ord() к обоим байтам, то получите вот такой результат:
$str = "Ф";
for ( $pos=0; $pos < strlen($str); $pos ++ ) {
 $byte = substr($str, $pos);
 echo 'Byte ' . $pos . ' of $str has value ' . ord($byte) . PHP_EOL;
}
// Byte 0 of $str has value 208
// Byte 1 of $str has value 164

Посмотрите описание юникодовской буквы 'Ф', обратите внимание, что бинарное представление это 11010000:10100100, первый байт 208, второй 164.
https://www.fileformat.info/info/unicode/char/424/...

А символ вообще состоит сразу из четырех байт.

Вам достаточно научиться читать файл по одному байту в бинарном виде, и тогда ни ord() ни charCodeAt() не понадобится, у вас сразу юудет бинарное представление этого байта.

просто нужно стартовые игровые пакеты запарсить.
у вас они в виде строки или это бинарник? Если бинарник, то и работайте с ним как с бинарником.
fReader.readAsArrayBuffer(file);
Все возможности для этого в js есть.
https://developer.mozilla.org/en-US/docs/Web/JavaS...
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы