bytes.fromhex() в PHP

Fivebam

Новичок
В Python есть функция bytes.fromhex(str). Предположим, что str у нас это
2cd2d948cfaf4b1097530f7c74fb6737 . В ответ от этой функции мы получим
b',\xd2\xd9H\xcf\xafK\x10\x97S\x0f|t\xfbg7' .

Сломал себе всю голову, гуглил часами. Каким кодом мне получить замену этой функции на PHP?
 

ksnk

прохожий
зачем голову ломать ?
PHP:
$hex = hex2bin("d0bfd180d0b8d0bcd0b5d18020d188d0b5d181d182d0bdd0b0d0b4d186d0b0d182d0b5d180d0b8d187d0bdd18bd18520d0b4d0b0d0bdd0bdd18bd185");
var_dump($hex);
hex2bin - не оно ?
 

fixxxer

К.О.
Партнер клуба
Оно, конечно.

Код:
$ php -r 'echo hex2bin("2cd2d948cfaf4b1097530f7c74fb6737");' | hexdump -C
00000000  2c d2 d9 48 cf af 4b 10  97 53 0f 7c 74 fb 67 37  |,..H..K..S.|t.g7|
Гуглится за 5 секунд, если что, я не знаю, что там гуглить часами.
 

Fivebam

Новичок
Оно, конечно.

Код:
$ php -r 'echo hex2bin("2cd2d948cfaf4b1097530f7c74fb6737");' | hexdump -C
00000000  2c d2 d9 48 cf af 4b 10  97 53 0f 7c 74 fb 67 37  |,..H..K..S.|t.g7|
Гуглится за 5 секунд, если что, я не знаю, что там гуглить часами.
разбил ты строку, а результат посмотри какой мне нужен
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
читай документацию по синтаксису языка https://www.php.net/manual/en/language.types.integer.php
хочешь синтаксис питона b',\xNNN' - пиши на питоне,
если задача - вывести из php в питоновской нотации, напиши преобразование

в школе учиться надо было - узнал бы разницу между данными и форматом представления данных
 
Последнее редактирование:

Вурдалак

Продвинутый новичок
Я так понял, ты говоришь не про bytes.fromhex(), а про какую-то внутреннюю функцию Python, которая так дампит бинарную строку в консоль.

Если она так дампит все не-UTF-8 последовательности и управляющие символы, то в целом интересная задача.

PHP:
$dump = preg_replace_callback(
    '/
        (?<utf8>
            [\x09\x0A\x0D\x20-\x7E]
            | [\xC2-\xDF][\x80-\xBF]
            | \xE0[\xA0-\xBF][\x80-\xBF]
            | [\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}
            | \xED[\x80-\x9F][\x80-\xBF]  
            | \xF0[\x90-\xBF][\x80-\xBF]{2}
            | [\xF1-\xF3][\x80-\xBF]{3} 
            | \xF4[\x80-\x8F][\x80-\xBF]{2}
        )
        |
        (?<trash>.)
    /xs',
    function (array $match) {
        if (isset($match['utf8']) && strlen($match['utf8']) > 0) {
            $char = $match['utf8'];
            if (strlen($char) === 1 && ord($char) < 31) {
                return '\x' . bin2hex($char);
            } else {
                return $char;
            }
        } else {
            return '\x' . bin2hex($match['trash']);
        }
    },
    hex2bin('2cd2d948cfaf4b1097530f7c74fb6737')
);

var_dump($dump);
string(34) ",\xd2\xd9HϯK\x10\x97S\x0f|t\xfbg7"
Но наверняка можно как-то проще/эффективнее это сделать.
 

Вурдалак

Продвинутый новичок
P.S. Единственное, нужно подкорректировать код для определения non-printable character. Вот это вот ord() < 31 — это неточно.
 

ksnk

прохожий
для non-printable строк я, обычно, json_encode использую. Дешево и сердито... Правда в этом случае дофига флагов пришлось дописывать
PHP:
echo json_encode(hex2bin("2cd2d948cfaf4b1097530f7c74fb6737"),
                 JSON_INVALID_UTF8_IGNORE + JSON_INVALID_UTF8_SUBSTITUTE+JSON_PARTIAL_OUTPUT_ON_ERROR);
Код:
",H\u03efK\u0010S\u000f|tg7"
хотя обратного преобразования не выйдет :)
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Я так понял, ты говоришь не про bytes.fromhex(), а про какую-то внутреннюю функцию Python, которая так дампит бинарную строку в консоль.

Если она так дампит все не-UTF-8 последовательности и управляющие символы, то в целом интересная задача.
в питоне есть базовый тип данных - byte https://docs.python.org/3/library/stdtypes.html#bytes
нет никакой функции, это просто синтаксис "Any binary values over 127 must be entered into bytes literals using the appropriate escape sequence",
в php, java, golang, js и т.д. используется тип string
 

Вурдалак

Продвинутый новичок
в питоне есть базовый тип данных - byte https://docs.python.org/3/library/stdtypes.html#bytes
нет никакой функции, это просто синтаксис "Any binary values over 127 must be entered into bytes literals using the appropriate escape sequence",
в php, java, golang, js и т.д. используется тип string
Ты просто вопроса не понял. Он хочет сдампить строку, как это делает Python:
Код:
>>> bytes.fromhex('2cd2d948cfaf4b1097530f7c74fb6737')
b',\xd2\xd9H\xcf\xafK\x10\x97S\x0f|t\xfbg7'
Такой дамп удобен для каких-нибудь логов, чтобы мусором вывод не забивать.
 

S.Chushkin

Пофигист
Но наверняка можно как-то проще/эффективнее это сделать.
Конечно:
PHP:
function HexToPrintable($hex) {
    return preg_replace_callback('/=(.{2})/',
        function($matches) { return '\x' . strtolower($matches[1]); },
        quoted_printable_encode(hex2bin($hex)));

}
PHP:
print_r([HexToPrintable('2cd2d948cfaf4b1097530f7c74fb6737'), ',\xd2\xd9H\xcf\xafK\x10\x97S\x0f|t\xfbg7']);
/*
Array
(
    [0] => ,\xd2\xd9H\xcf\xafK\x10\x97S\x0f|t\xfbg7
    [1] => ,\xd2\xd9H\xcf\xafK\x10\x97S\x0f|t\xfbg7
)
*/
 

Вурдалак

Продвинутый новичок
Конечно:
PHP:
function HexToPrintable($hex) {
    return preg_replace_callback('/=(.{2})/',
        function($matches) { return '\x' . strtolower($matches[1]); },
        quoted_printable_encode(hex2bin($hex)));

}
PHP:
print_r([HexToPrintable('2cd2d948cfaf4b1097530f7c74fb6737'), ',\xd2\xd9H\xcf\xafK\x10\x97S\x0f|t\xfbg7']);
/*
Array
(
    [0] => ,\xd2\xd9H\xcf\xafK\x10\x97S\x0f|t\xfbg7
    [1] => ,\xd2\xd9H\xcf\xafK\x10\x97S\x0f|t\xfbg7
)
*/
Ну это не совсем аналог. Твоя функция не тронет, например, 0xff, который не является валидным байтом для UTF-8 и в большинстве консолей отобразится как мусорный символ.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
Ты просто вопроса не понял. Он хочет сдампить строку, как это делает Python:
Такой дамп удобен для каких-нибудь логов, чтобы мусором вывод не забивать.
одна проблема: у ТС на входе уже есть представление данных в виде hex-строки, ее уже можно записать в лог
 

Вурдалак

Продвинутый новичок
одна проблема: у ТС на входе уже есть представление данных в виде hex-строки, ее уже можно записать в лог
В большинстве случаев никто не хочет видеть в логе «2cd2d948cfaf4b1097530f7c74fb6737», когда всего пара символов non-printable. А в большинстве случаев строки вообще могут отображаться как есть.
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
теперь понятно :)
правда, появляется вопрос как же это у него строка в hex преобразовалась :)
когда берешь, например, даные из php://input - они в бинарном виде
 

fixxxer

К.О.
Партнер клуба
разбил ты строку, а результат посмотри какой мне нужен
А результат у тебя, внезапно, такой же.

В ответ от этой функции мы получим
бинарную строку, идентичную той, которая в php получена через hex2bin. А такое представление
b',\xd2\xd9H\xcf\xafK\x10\x97S\x0f|t\xfbg7
это просто результат вывода на экран стандартным Питоновским print-ом.

Если тебе нужен именно питоновский print на php (но зачем?) - тогда так и спрашивай, преобразование из hex к этому не имеет никакого отношения.
 
Сверху