Wie kann ich einen Hex-Dump einer Zeichenfolge in PHP erhalten?

Lesezeit: 7 Minuten

Ich untersuche Codierungen in PHP5. Gibt es eine Möglichkeit, einen rohen Hex-Dump einer Zeichenfolge zu erhalten? dh eine Hex-Darstellung von jedem der Bytes (nicht Zeichen) in einer Zeichenfolge?

  • Ein nettes kleines Online-Tool srsbiz.pl/utils/hexit.php und seine PHP-Quelle: gist.github.com/4639219 – könnte nützlich sein, Credits/Danke @dev-null-dweller

    – hakre

    26. Januar 2013 um 0:41 Uhr

  • github.com/clue/php-hexdump

    – Bischof

    12. Mai 2017 um 14:45 Uhr

Wie kann ich einen Hex Dump einer Zeichenfolge in PHP erhalten
Stefan Gehrig

echo bin2hex($string);

oder:

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

$string ist die Variable, die Eingaben enthält.

  • Oder ein funktionalerer Ansatz: print_r(array_map(‘dechex’, array_map(‘ord’, str_split($string))));

    – Ionuț G. Stan

    29. Juni 2009 um 10:29 Uhr

1647285845 71 Wie kann ich einen Hex Dump einer Zeichenfolge in PHP erhalten
mindplay.dk

Für Debugging-Arbeiten mit Binärprotokollen brauchte ich einen traditionelleren HEX-Dump, also schrieb ich diese Funktion:

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

Dies erzeugt einen traditionelleren HEX-Dump wie diesen:

hex_dump($data);

=>

 0 : 05 07 00 00 00 64 65 66 61 75 6c 74 40 00 00 00 [[email protected]]
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]

Beachten Sie, dass nicht sichtbare Zeichen durch einen Punkt ersetzt werden – Sie können die Anzahl der Bytes pro Zeile ($width) und Füllzeichen ($pad) Ihren Anforderungen entsprechend ändern. Ich habe ein $newline-Argument eingefügt, damit Sie bestehen können "<br/>" wenn Sie die Ausgabe in einem Browser anzeigen müssen.

  • +1 ausgezeichnet. Zu ausgezeichnet. Ich habe über vier Stunden an etwas gearbeitet und das hat mich einfach angespornt. Wie auch immer, ich habe festgestellt, dass das Echo eines Pre-Tags es in einem Browser besser anzeigt. Oder mit br newline. Ich bin neu dabei und frage mich, wie ich die nicht sichtbaren Zeichen entschlüsseln kann. TNX.

    – frostigwunderbar

    22. August 2011 um 16:54 Uhr

  • Liebe es! Benötigt einige Verbesserungen, aber als Basis für das Debugging-Tool ist es perfekt!

    – Ruben Kasumow

    15. August 2012 um 2:05 Uhr

  • @frostymarvelous für Nur-Text-Diagnoseausgabe in einem Browser versuchen header('Content-type: text/plain'); – praktisch 🙂

    – mindplay.dk

    15. August 2012 um 15:03 Uhr

  • das ist im Wesentlichen so, als würde man eine machen od -tx1z

    – Walter Tross

    31. März 2013 um 0:57 Uhr

  • Bitte geben Sie einen Wert für $data an.

    – SwR

    30. Juni 2016 um 3:58 Uhr

Es ist Jahre später, aber für den Fall, dass andere auch danach suchen, habe ich mir die Freiheit genommen, den Code von mindplay.dk zu ändern, damit er verschiedene Optionen akzeptiert und die Ausgabe der BSD-Befehlsdatei hexdump -C simuliert:

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

und dies ist ein Hex-Dump einer kleinen Datei:

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

und das ist der phpunit test:

<?php
if (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__ . "https://stackoverflow.com/" . 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);
    }
}

  • Die letzte Zeile 00000086 ist nutzlos.

    – Bartosz Wójcik

    16. Januar 2016 um 17:26 Uhr

  • Sagen Sie das dem Autor des BSD-Befehls hexdump. Die letzte Zeile gibt die Dateigröße an.

    – Interner Serverfehler

    15. Februar 2016 um 2:52 Uhr


Wie kann ich einen Hex Dump einer Zeichenfolge in PHP erhalten
hek2mgl

Beim Debuggen eines Binärprotokolls brauchte ich auch ein hexdump(). Ich habe mich entschieden, meine Lösung als PEAR-Paket zu veröffentlichen, da sie definitiv nützlich ist. Sie können den Code auch auf github durchsuchen.

BIRNE : http://www.metashock.de/pear

GitHub: http://www.github.com/metashock/Hexdump

Zusätzlich zur Mindplays-Lösung unterstützt es das korrekte Rendern der letzten Zeile und zusätzlicher Parameter. Das Paket enthält auch eine ausführbare PHP-Datei namens phphd für Hexdumps auf cmdline. Dies könnte auf Windows-Systemen hilfreich sein 🙂

@mindplay.dk : Danke für die strtr()-Idee. Es schien etwas schneller zu sein als mein früherer Versuch. Habe das in meine Version integriert. (Verwendung eines verringerten Übersetzungspuffers)..

Wie kann ich einen Hex Dump einer Zeichenfolge in PHP erhalten
x-yuri

“Funktionale” Version:

$s = "\x04\x00\xa0\x00";
echo implode(' ', array_map(function($char) {
    # return sprintf('%02s', $char);
    return str_pad($char, 2, '0', STR_PAD_LEFT);
}, array_map('dechex', unpack('C*', $s))));

In Anlehnung an den Kommentar von Ionuț G. Stan könnte die letzte Zeile wie folgt lauten:

}, array_map('dechex', array_map('ord', str_split($s)))));

1647285846 956 Wie kann ich einen Hex Dump einer Zeichenfolge in PHP erhalten
Benutzer13104741

    echo implode(array_map(
        fn ($a, $b) => sprintf("%-26s%-8s\n", $a, $b), 
        str_split(implode(' ', str_split(bin2hex($string), 2)), 24),
        str_split($string, 8)
    ));

1002880cookie-checkWie kann ich einen Hex-Dump einer Zeichenfolge in PHP erhalten?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy