How can I get a hex dump of a string in PHP? How can I get a hex dump of a string in PHP? php php

How can I get a hex dump of a string in PHP?


echo bin2hex($string);

or:

for ($i = 0; $i < strlen($string); $i++) {    echo str_pad(dechex(ord($string[$i])), 2, '0', STR_PAD_LEFT);}

$string is the variable which contains input.


For debugging work with binary protocols, I needed a more traditional HEX dump, so I wrote this function:

function hex_dump($data, $newline="\n"){  static $from = '';  static $to = '';  static $width = 16; # number of bytes per line  static $pad = '.'; # padding for non-visible characters  if ($from==='')  {    for ($i=0; $i<=0xFF; $i++)    {      $from .= chr($i);      $to .= ($i >= 0x20 && $i <= 0x7E) ? chr($i) : $pad;    }  }  $hex = str_split(bin2hex($data), $width*2);  $chars = str_split(strtr($data, $from, $to), $width);  $offset = 0;  foreach ($hex as $i => $line)  {    echo sprintf('%6X',$offset).' : '.implode(' ', str_split($line,2)) . ' [' . $chars[$i] . ']' . $newline;    $offset += $width;  }}

This produces a more traditional HEX dump, like this:

hex_dump($data);=> 0 : 05 07 00 00 00 64 65 66 61 75 6c 74 40 00 00 00 [.....default@...]10 : 31 42 38 43 39 44 30 34 46 34 33 36 31 33 38 33 [1B8C9D04F4361383]20 : 46 34 36 32 32 46 33 39 32 46 44 38 43 33 42 30 [F4622F392FD8C3B0]30 : 45 34 34 43 36 34 30 33 36 33 35 37 45 35 33 39 [E44C64036357E539]40 : 43 43 38 44 35 31 34 42 44 36 39 39 46 30 31 34 [CC8D514BD699F014]

Note that non-visible characters are replaced with a period - you can change the number of bytes per line ($width) and padding character ($pad) to suit your needs. I included a $newline argument, so you can pass "<br/>" if you need to display the output in a browser.

Hope this is useful :-)


It's years later, but in case others are searching for this too, I took the liberty to modify mindplay.dk's code to make it accept various options and simulate the output of the BSD command hexdump -C file:

/*** Dumps a string into a traditional hex dump for programmers,* in a format similar to the output of the BSD command hexdump -C file.* The default result is a string.* Supported options:* <pre>*   line_sep        - line seperator char, default = "\n"*   bytes_per_line  - default = 16*   pad_char        - character to replace non-readble characters with, default = '.'* </pre>** @param string $string* @param array $options* @param string|array*/function hex_dump($string, array $options = null) {    if (!is_scalar($string)) {        throw new InvalidArgumentException('$string argument must be a string');    }    if (!is_array($options)) {        $options = array();    }    $line_sep       = isset($options['line_sep'])   ? $options['line_sep']          : "\n";    $bytes_per_line = @$options['bytes_per_line']   ? $options['bytes_per_line']    : 16;    $pad_char       = isset($options['pad_char'])   ? $options['pad_char']          : '.'; # padding for non-readable characters    $text_lines = str_split($string, $bytes_per_line);    $hex_lines  = str_split(bin2hex($string), $bytes_per_line * 2);    $offset = 0;    $output = array();    $bytes_per_line_div_2 = (int)($bytes_per_line / 2);    foreach ($hex_lines as $i => $hex_line) {        $text_line = $text_lines[$i];        $output []=            sprintf('%08X',$offset) . '  ' .            str_pad(                strlen($text_line) > $bytes_per_line_div_2                ?                    implode(' ', str_split(substr($hex_line,0,$bytes_per_line),2)) . '  ' .                    implode(' ', str_split(substr($hex_line,$bytes_per_line),2))                :                implode(' ', str_split($hex_line,2))            , $bytes_per_line * 3) .            '  |' . preg_replace('/[^\x20-\x7E]/', $pad_char, $text_line) . '|';        $offset += $bytes_per_line;    }    $output []= sprintf('%08X', strlen($string));    return @$options['want_array'] ? $output : join($line_sep, $output) . $line_sep;}

and this is a hex dump of a small file:

00000000  89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.PNG........IHDR|00000010  00 00 00 10 00 00 00 10  02 03 00 00 00 62 9d 17  |.............b..|00000020  f2 00 00 00 09 50 4c 54  45 04 04 04 99 99 cc d7  |.....PLTE.......|00000030  d7 d7 2a 66 f6 6b 00 00  00 38 49 44 41 54 78 9c  |..*f.k...8IDATx.|00000040  63 08 05 02 06 24 22 0b  44 24 01 89 ac a4 69 4b  |c....$".D$....iK|00000050  19 1a 16 68 70 31 74 29  75 2c 42 22 1a 16 75 00  |...hp1t)u,B"..u.|00000060  c5 22 33 96 32 74 86 46  4c 65 58 19 1a 35 15 61  |."3.2t.FLeX..5.a|00000070  00 00 df be 19 a6 2e 62  80 87 00 00 00 00 49 45  |.......b......IE|00000080  4e 44 ae 42 60 82                                 |ND.B`.|00000086

and this is the phpunit test:

<?phpif (isset($argv)) {    print "Running outside of phpunit. Consider using phpunit.\n";    class PHPUnit_Framework_TestCase {}}class Test extends PHPUnit_Framework_TestCase{    const FUNCTION_NAME = 'hex_dump';    const DATA_BASE64 = '        iVBORw0KGgoAAAANSUhEUgAAABAAAAAQAgMAAABinRfyAAAACVBMVEUEBASZmczX19cqZvZrAAAA        OElEQVR4nGMIBQIGJCILRCQBiaykaUsZGhZocDF0KXUsQiIaFnUAxSIzljJ0hkZMZVgZGjUVYQAA        374Zpi5igIcAAAAASUVORK5CYII=';    private $expect = array(        '00000000  89 50 4e 47 0d 0a 1a 0a  00 00 00 0d 49 48 44 52  |.PNG........IHDR|',        '00000010  00 00 00 10 00 00 00 10  02 03 00 00 00 62 9d 17  |.............b..|',        '00000020  f2 00 00 00 09 50 4c 54  45 04 04 04 99 99 cc d7  |.....PLTE.......|',        '00000030  d7 d7 2a 66 f6 6b 00 00  00 38 49 44 41 54 78 9c  |..*f.k...8IDATx.|',        '00000040  63 08 05 02 06 24 22 0b  44 24 01 89 ac a4 69 4b  |c....$".D$....iK|',        '00000050  19 1a 16 68 70 31 74 29  75 2c 42 22 1a 16 75 00  |...hp1t)u,B"..u.|',        '00000060  c5 22 33 96 32 74 86 46  4c 65 58 19 1a 35 15 61  |."3.2t.FLeX..5.a|',        '00000070  00 00 df be 19 a6 2e 62  80 87 00 00 00 00 49 45  |.......b......IE|',        '00000080  4e 44 ae 42 60 82                                 |ND.B`.|',        '00000086',    );    public function testRequire() {        $file = __DIR__ . '/' . static::FUNCTION_NAME . '.php';        $this->assertFileExists($file);        include($file);        $this->assertTrue(function_exists(static::FUNCTION_NAME));    }    public function testString() {        $func = static::FUNCTION_NAME;        $data = base64_decode(static::DATA_BASE64);        if (!is_string($data)) {            throw new Exception('Unable to decode base64 encoded test data');        }        $dump = $func($data);        //var_export($dump);        $this->assertTrue(is_string($dump));        $this->assertEquals($dump, join("\n", $this->expect) . "\n");    }}if (isset($argv)) {    $func = Test::FUNCTION_NAME;    require_once($func . '.php');    if (count($argv) < 2) {        print "Pass arguments file, from, length.\n";    }    else {        $file = $argv[1];        if (!file_exists($file)) {            die("File not found: $file\n");        }        $from   = isset($argv[2]) && preg_match('/^\d{1,9}$/', $argv[2]) ? intval($argv[2]) : null;        $len    = isset($argv[3]) && preg_match('/^\d{1,9}$/', $argv[3]) ? intval($argv[3]) : filesize($file);        $h = fopen($file, 'r');        if ($from) {            fseek($h, $from);        }        $data = fread($h, $len);        fclose($h);        $dump = hex_dump($data);        print $dump;        //$dump = hex_dump($data, array('want_array' => true));        //print_r($dump);    }}