Функции C++ HexToBin VS PHP Hex2Bin. Другой вывод

У меня есть следующая строка в моих сценариях PHP и C++:

152F302436152F302435152F302434152F302433152F302433

В PHP я использую встроенную функцию hex2bin как:

<?php
    $HEXString = "152F302436152F302435152F302434152F302433152F302433";
    echo hex2bin($HEXString);
    //Outputs: /0$6/0$5/0$4/0$3/0$3 
    ?>

Однако в C++ я использую следующие функции, чтобы выполнить то же самое с совершенно другим результатом:

const char* HexCharToBin(char c) {
    char cUpper = toupper(c);
    if (cUpper == '0') return "0000";
    else if (cUpper == '1') return "0001";
    else if (cUpper == '2') return "0010";
    else if (cUpper == '3') return "0011";
    else if (cUpper == '4') return "0100";
    else if (cUpper == '5') return "0101";
    else if (cUpper == '6') return "0110";
    else if (cUpper == '7') return "0111";
    else if (cUpper == '8') return "1000";
    else if (cUpper == '9') return "1001";
    else if (cUpper == 'A') return "1010";
    else if (cUpper == 'B') return "1011";
    else if (cUpper == 'C') return "1100";
    else if (cUpper == 'D') return "1101";
    else if (cUpper == 'E') return "1110";
    else if (cUpper == 'F') return "1111";
    else return "0000";
    }
string HexToBin(const string& hex) {
    string bin;
    for (unsigned i = 0; i != hex.length(); ++i) {
        bin += HexCharToBin(hex[i]);
        }
    return bin;
    }

Код на С++:

cout << HexToBin("152F302436152F302435152F302434152F302433152F302433") << endl;
//Outputs: 00010101001011110011000000100100001101100001010100101111001100000010010000110101000101010010111100110000001001000011010000010101001011110011000000100100001100110001010100101111001100000010010000110011

Я хочу, чтобы С++ достиг той же строки, что и PHP. Что я здесь делаю неправильно?


person TVA van Hesteren    schedule 02.11.2017    source источник
comment
C++ и PHP — два совершенно разных языка. Проведение параллелей между ними может оказаться контрпродуктивным.   -  person Ron    schedule 02.11.2017
comment
Не знаком с PHP, но как /0$6/0$5/0$4/0$3/0$3 соответствует "152F302436152F302435152F302434152F302433152F302433"?   -  person Stephan Lechner    schedule 02.11.2017
comment
@StephanLechner, без понятия, но именно так работает функция hex2bin-PHP...   -  person TVA van Hesteren    schedule 02.11.2017
comment
@ Рон, верно, но можно ли добиться того же результата на C ++, что и на PHP?   -  person TVA van Hesteren    schedule 02.11.2017
comment
Символ 1 (вероятно) представлен целочисленным значением 49, 2 представлен 50 и так далее. В C++ символы — это символы. К ним привязаны базовые интегральные значения.   -  person Ron    schedule 02.11.2017
comment
Не могу опубликовать ответ, так как я не работаю на С++, но одна вещь, безусловно, неправильная в вашем коде, это то, что вы переводите один символ за раз. В шестнадцатеричной системе счисления 15 — это одна цифра. Кроме того, вы возвращаете строку цифр в двоичной записи вместо фактической двоичной строки.   -  person Narf    schedule 02.11.2017


Ответы (3)


Если вы просто хотите преобразовать шестнадцатеричное число в двоичное, используйте base_convert().

Внимательно прочитайте hex2bin php документацию, в которой цитируется:

Внимание Эта функция НЕ преобразует шестнадцатеричное число в двоичное. Это можно сделать с помощью функции base_convert().

Эта функция просто

Декодирует шестнадцатеричную двоичную строку.

Итак, поскольку ваша строка не является шестнадцатеричной строкой, вы получаете неожиданный/другой вывод.

Чтобы воспроизвести поведение hex2bin в php, вам может помочь следующий пост: Отсутствует пунктуация из C++ hex2bin

Надеюсь, это помогло.

person Parantap Parashar    schedule 02.11.2017
comment
Спасибо за комментарий. Однако я бы хотел, чтобы поведение PHP было реализовано на C++. Как я могу этого добиться? Итак, в основном мне нужно, чтобы C++ генерировал тот же вывод, что и PHP. - person TVA van Hesteren; 02.11.2017
comment
@TVAvanHesteren: Пожалуйста, проверьте обновленную ссылку. Это может помочь вам. - person Parantap Parashar; 02.11.2017
comment
Я попробовал ссылку, и когда я ввожу свою HEXString, она не дает мне того же результата, что и PHP? - person TVA van Hesteren; 02.11.2017
comment
@TVAvanHesteren: Хорошо, тогда я не смогу вам помочь, так как я не так хорошо знаком с С++. Однако вы можете использовать c и воспроизвести поведение, увидев реализацию hex2bin в php-src: ссылка. - person Parantap Parashar; 02.11.2017

<?php
    $HEXString = "152F302436152F302435152F302434152F302433152F302433";
    echo base_convert(hex2bin($HEXString), 16, 2);
?>

Я думаю, что этот подход вернет то, что вы ищете, или вы можете просто сделать ту же функцию, которую вы сделали на С++ на PHP, используя Array, например:

$base = array(
'1'=>"0001",
'2'=>"0010",
'3'=>"0011",
...
);
function HexToBin($string) {
$len = strlen($string);
$bin;
    for ($i = 0; $i < $len; $i++) {
        $bin += $base[$string[$i]];
        }
    return $bin;
    }
echo HexToBin("152F302436152F302435152F302434152F302433152F302433");
//Outputs: 00010101001011110011000000100100001101100001010100101111001100000010010000110101000101010010111100110000001001000011010000010101001011110011000000100100001100110001010100101111001100000010010000110011
person Matheus Dadalto    schedule 02.11.2017

Я хочу, чтобы С++ достиг той же строки, что и PHP. Что я здесь делаю неправильно?

что делать, если вы знаете, что вывод PHP является неправильным выводом, и это не так, но в PHP это нормальное поведение hex2bin.

вам нужно сначала преобразовать hex string в десятичное значение, используя hexdec, а затем преобразовать десятичное число в двоичное, используя decbin .

$hex = decbin(
    hexdec("152F302436152F302435152F302434152F302433152F302433")
);
echo $bin;

это вызовет проблему из-за целочисленного ограничения PHP

на странице руководства decbin вы можете перейти в раздел Параметры чтобы узнать об этом больше.


вы можете написать функцию PHP для достижения того же результата, что и на стороне C++, или использовать расширение GMP, чтобы получить пробный вывод из приведенного выше примера.

function _hex2bin($hex)
{
    $hex = strtoupper($hex);
    $hexLen = strlen($hex);
    $bin = [];
    for ($i = 0; $i < $hexLen; $i++) {
        $char = $hex[$i];
        if ($char == '0') $bin[] = "0000";
        else if ($char == '1') $bin[] = "0001";
        else if ($char == '2') $bin[] = "0010";
        else if ($char == '3') $bin[] = "0011";
        else if ($char == '4') $bin[] = "0100";
        else if ($char == '5') $bin[] = "0101";
        else if ($char == '6') $bin[] = "0110";
        else if ($char == '7') $bin[] = "0111";
        else if ($char == '8') $bin[] = "1000";
        else if ($char == '9') $bin[] = "1001";
        else if ($char == 'A') $bin[] = "1010";
        else if ($char == 'B') $bin[] = "1011";
        else if ($char == 'C') $bin[] = "1100";
        else if ($char == 'D') $bin[] = "1101";
        else if ($char == 'E') $bin[] = "1110";
        else if ($char == 'F') $bin[] = "1111";
        else $bin[] = "0000";
    }

    return implode("", $bin);
}

echo _hex2bin("152F302436152F302435152F302434152F302433152F302433");

живой образец: https://3v4l.org/IkRmG

или еще короче:

function _hex2bin($hex)
{
    $hex = strtoupper($hex);
    $hexLen = strlen($hex);
    $bin = [];
    for ($i = 0; $i < $hexLen; $i++) {
        $char = $hex[$i];
        $bin[] = str_pad(base_convert($char, 16, 2), 4, '0', STR_PAD_LEFT);
    }

    return implode("", $bin);
}

echo _hex2bin("152F302436152F302435152F302434152F302433152F302433");

живой пример: https://3v4l.org/MoH8R

person hassan    schedule 02.11.2017