1

I have the following string in both my PHP and C++ scripts:

152F302436152F302435152F302434152F302433152F302433

In PHP I use the built-in hex2bin function as:

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

However, in C++ I use the following functions to accomplish the same with a complete other result:

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;
    }

The code in C++:

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

I want C++ to achieve the same string as PHP returns. What am I doing wrong here?

TVA van Hesteren
  • 1,031
  • 3
  • 20
  • 47
  • C++ and PHP are two completely different languages. Drawing parallels between the two can prove to be counter-productive. – Ron Nov 02 '17 at 10:52
  • 1
    Not familar with PHP, but how does `/0$6/0$5/0$4/0$3/0$3` correspond to `"152F302436152F302435152F302434152F302433152F302433"`? – Stephan Lechner Nov 02 '17 at 10:52
  • @StephanLechner, no idea but that is how the hex2bin-PHP function seems to work... – TVA van Hesteren Nov 02 '17 at 10:56
  • @Ron, right but is it possible to achieve the same result in C++ as in PHP? – TVA van Hesteren Nov 02 '17 at 10:57
  • Character `1` is (probably) represented by an integer value of `49`, `2` is represented by `50` and so on. In C++ characters are characters. They have underlying integral values attached to them. – Ron Nov 02 '17 at 10:57
  • Can't post an answer as I don't do C++, but the one thing certainly wrong with your code is that you're translating a single character at a time. In hexadecimal notation, "15" is a *single digit*. Also, you're returning a string of binary-notation digits instead of an actual binary string. – Narf Nov 02 '17 at 11:50

3 Answers3

0

If you just want to convert a hexadecimal number to a binary number use base_convert().

Read the hex2bin php documentation carefully it quotes:

Caution This function does NOT convert a hexadecimal number to a binary number. This can be done using the base_convert() function.

This function simply

Decodes a hexadecimally encoded binary string.

So, as your string is not a hexadecimally encoded string, you are getting a unexpected/different output.

To replicate the behavior of php's hex2bin, following post can help you: Missing punctuation from C++ hex2bin

Hope it helped.

Parantap Parashar
  • 1,930
  • 1
  • 14
  • 22
  • Thanks for the comment. However, I would like the behaviour of PHP implemented in C++. How can I achieve this? So, basically I need C++ to generate the same output as PHP does – TVA van Hesteren Nov 02 '17 at 10:50
  • @TVAvanHesteren: Please check the updated link. It can help you. – Parantap Parashar Nov 02 '17 at 10:57
  • I have tried the link and when I input my HEXString it is not giving me the same output as PHP does? – TVA van Hesteren Nov 02 '17 at 11:14
  • @TVAvanHesteren: Okay, I will not be able to help you then as I am not so familiar with c++. However, you can use c and replicate the behavior by seeing the implementation of hex2bin in [php-src : link](https://github.com/php/php-src/blob/master/ext/standard/string.c). – Parantap Parashar Nov 02 '17 at 11:18
0
<?php
    $HEXString = "152F302436152F302435152F302434152F302433152F302433";
    echo base_convert(hex2bin($HEXString), 16, 2);
?>

I think this approach would return what you are looking for, or you can simple make the same function you made on C++ on PHP using Array such:

$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
0

I want C++ to achieve the same string as PHP returns. What am I doing wrong here?

what to do when you know that the PHP output is the wrong output, and this is not a but in PHP, it's the normal behavior of hex2bin function.

you need first to convert your hex string into a decimal value using hexdec and after that convert your decimal into binary using decbin .

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

this will cause a problem because of the PHP integer limitation

in the decbin manual page you may navigate to Parameters section to know more about that.


you may write a PHP function to achieve the same result as C++ side, or use GMP extension to get the prober output from the above example.

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");

live sample : https://3v4l.org/IkRmG

or even shorter :

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");

live sample : https://3v4l.org/MoH8R

hassan
  • 7,812
  • 2
  • 25
  • 36