78

I got the problem when convert between this 2 type in PHP. This is the code I searched in google

function strToHex($string){
    $hex='';
    for ($i=0; $i < strlen($string); $i++){
        $hex .= dechex(ord($string[$i]));
    }
    return $hex;
}


function hexToStr($hex){
    $string='';
    for ($i=0; $i < strlen($hex)-1; $i+=2){
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    return $string;
}

I check it and found out this when I use XOR to encrypt.

I have the string "this is the test", after XOR with a key, I have the result in string ↕↑↔§P↔§P ♫§T↕§↕. After that, I tried to convert it to hex by function strToHex() and I got these 12181d15501d15500e15541215712. Then, I tested with the function hexToStr() and I have ↕↑↔§P↔§P♫§T↕§q. So, what should I do to solve this problem? Why does it wrong when I convert this 2 style value?

4
  • 10
    You know there are hex2bin() and bin2hex() in PHP? Commented Feb 3, 2013 at 17:00
  • strToHex returns a string of hex - so if you XOR that directly with the ^ operator, that won't give any good result. Maybe you could give strToHex another param being the number you want to XOR with, and XOR directly inside that function: $hex .= dechex(ord($string[$i]) ^ $MYKEYBYTE); Commented Feb 3, 2013 at 17:02
  • I thought that the problem is at hexToStr() function. Because when it convert to string, it pass the space or some special character, and make the problem Commented Feb 3, 2013 at 17:16
  • I tried hex2bin() and bin2hex(). It's really good and solve this. but in real situation, It doesn't. It just be right if I call bin2hex() function after encrypt by XOR the plaintext with key. But in a real situation, we usually use strToHex() after XOR , so when we decrypt by XOR the Crypt with KEY to get the plaintext, we call the hexToStr() It will get wrong result. Commented Feb 3, 2013 at 17:22

9 Answers 9

156

For people that end up here and are just looking for the hex representation of a (binary) string.

bin2hex("that's all you need");
# 74686174277320616c6c20796f75206e656564

hex2bin('74686174277320616c6c20796f75206e656564');
# that's all you need

Doc: bin2hex, hex2bin.

Sign up to request clarification or add additional context in comments.

1 Comment

I made a gist that incorporated this. A simple hex dumper function for PHP: gist.github.com/hopeseekr/9964a9f12428dd220c3dd29a9943ce65
57

For any char with ord($char) < 16 you get a HEX back which is only 1 long. You forgot to add 0 padding.

This should solve it:

<?php
function strToHex($string){
    $hex = '';
    for ($i=0; $i<strlen($string); $i++){
        $ord = ord($string[$i]);
        $hexCode = dechex($ord);
        $hex .= substr('0'.$hexCode, -2);
    }
    return strToUpper($hex);
}
function hexToStr($hex){
    $string='';
    for ($i=0; $i < strlen($hex)-1; $i+=2){
        $string .= chr(hexdec($hex[$i].$hex[$i+1]));
    }
    return $string;
}


// Tests
header('Content-Type: text/plain');
function test($expected, $actual, $success) {
    if($expected !== $actual) {
        echo "Expected: '$expected'\n";
        echo "Actual:   '$actual'\n";
        echo "\n";
        $success = false;
    }
    return $success;
}

$success = true;
$success = test('00', strToHex(hexToStr('00')), $success);
$success = test('FF', strToHex(hexToStr('FF')), $success);
$success = test('000102FF', strToHex(hexToStr('000102FF')), $success);
$success = test('↕↑↔§P↔§P ♫§T↕§↕', hexToStr(strToHex('↕↑↔§P↔§P ♫§T↕§↕')), $success);

echo $success ? "Success" : "\nFailed";

1 Comment

In the strToHex function, as an alternative to the whole dechex() and substr -2, one may just use: $hex .= sprintf('%02.x', $ord);
39

PHP :

string to hex:

implode(unpack("H*", $string));

hex to string:

pack("H*", $hex);

2 Comments

You could avoid the call to implode by using list, ie: list(, $hex) = unpack('H*', $string);
The HEX value of 64 is 40. But it's returning me something else
13

Here's what I use:

function strhex($string) {
  $hexstr = unpack('H*', $string);
  return array_shift($hexstr);
}

Comments

2

Here's how to convert hex to string:

    $s = '\x64\x65';
    $t = array_map(function($item){
        return pack("H*", $item);
    }, explode('/x', $s));
    $result = implode('', $t);

Comments

1
function hexToStr($hex){
    // Remove spaces if the hex string has spaces
    $hex = str_replace(' ', '', $hex);
    return hex2bin($hex);
}
// Test it 
$hex    = "53 44 43 30 30 32 30 30 30 31 37 33";
echo hexToStr($hex); // SDC002000173

/**
 * Test Hex To string with PHP UNIT
 * @param  string $value
 * @return 
 */
public function testHexToString()
{
    $string = 'SDC002000173';
    $hex    = "53 44 43 30 30 32 30 30 30 31 37 33";
    $result = hexToStr($hex);

    $this->assertEquals($result,$string);
}

Comments

1

Using @bill-shirley answer with a little addition

function str_to_hex($string) {
$hexstr = unpack('H*', $string);
return array_shift($hexstr);
}
function hex_to_str($string) {
return hex2bin("$string");
}

Usage:

  $str = "Go placidly amidst the noise";
  $hexstr = str_to_hex($str);// 476f20706c616369646c7920616d6964737420746865206e6f697365
  $strstr = hex_to_str($str);// Go placidly amidst the noise

2 Comments

Why not convert the accented characters first
Any particular approach recommended? mb_convert_encoding? This is outside the original scope, but the hex information will be converted back into string in MSSQL, which doesn't have a decoding function.
1

I only have half the answer, but I hope that it is useful as it adds unicode (utf-8) support

    /**
     * hexadecimal to unicode character
     * @param  string  $hex
     * @return string
     */
    function hex2uni($hex) { 
      $dec = hexdec($hex);
        if($dec < 128) {
            return chr($dec);
        }
        if($dec < 2048) {
            $utf = chr(192 + (($dec - ($dec % 64)) / 64));
        } else {
            $utf = chr(224 + (($dec - ($dec % 4096)) / 4096));
            $utf .= chr(128 + ((($dec % 4096) - ($dec % 64)) / 64));
        }
        return $utf . chr(128 + ($dec % 64));
    }

To string

    var_dump(hex2uni('e641'));

Based on: http://www.php.net/manual/en/function.chr.php#Hcom55978

Comments

0

You can try the following code to convert the image to hex string

<?php
$image = 'sample.bmp';
$file = fopen($image, 'r') or die("Could not open $image");
while ($file && !feof($file)){
$chunk = fread($file, 1000000); # You can affect performance altering
this number. YMMV.
# This loop will be dog-slow, almost for sure...
# You could snag two or three bytes and shift/add them,
# but at 4 bytes, you violate the 7fffffff limit of dechex...
# You could maybe write a better dechex that would accept multiple bytes
# and use substr... Maybe.
for ($byte = 0; $byte < strlen($chunk); $byte++)){
echo dechex(ord($chunk[$byte]));
}
}
?>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.