복붙노트

어떻게 PHP에서 문자열의 16 진 덤프를 얻을 수 있습니까?

PHP

어떻게 PHP에서 문자열의 16 진 덤프를 얻을 수 있습니까?

PHP5에서 인코딩을 조사하고 있습니다. 문자열의 원시 16 진 덤프를 가져 오는 방법이 있습니까? 문자열의 각 바이트 (문자 아님)의 16 진수 표현?

해결법

  1. ==============================

    1.

    echo bin2hex($string);
    

    또는:

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

    $ string은 입력을 포함하는 변수입니다.

  2. ==============================

    2.바이너리 프로토콜을 사용하는 디버깅 작업을 위해 좀 더 전통적인 HEX 덤프가 필요했기 때문에이 함수를 작성했습니다.

    바이너리 프로토콜을 사용하는 디버깅 작업을 위해 좀 더 전통적인 HEX 덤프가 필요했기 때문에이 함수를 작성했습니다.

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

    이렇게하면 다음과 같이보다 전통적인 HEX 덤프가 생성됩니다.

    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]
    

    보이지 않는 문자는 마침표로 대체됩니다. 필요에 맞게 줄당 바이트 수 ($ width)와 여백 문자 ($ pad)를 변경할 수 있습니다. $ 개행 인수가 포함되어 있으므로 출력을 브라우저에 표시해야하는 경우 "
    "을 전달할 수 있습니다.

    희망이 유용합니다 :-)

  3. ==============================

    3.몇 년 후이지만, 다른 사람들이 이것을 찾고있는 중이라면 mindplay.dk의 코드를 수정하여 다양한 옵션을 허용하고 BSD 명령 hexdump -C 파일의 출력을 시뮬레이트 할 자유를 얻었습니다.

    몇 년 후이지만, 다른 사람들이 이것을 찾고있는 중이라면 mindplay.dk의 코드를 수정하여 다양한 옵션을 허용하고 BSD 명령 hexdump -C 파일의 출력을 시뮬레이트 할 자유를 얻었습니다.

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

    이것은 작은 파일의 16 진 덤프입니다.

    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
    

    이것은 phpunit 테스트입니다.

    <?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__ . '/' . 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);
        }
    }
    
  4. ==============================

    4.바이너리 프로토콜을 디버깅하는 동안 나는 hexdump ()도 필요로했다. 분명히 유용하기 때문에 내 솔루션을 PEAR 패키지로 게시하기로 결정했습니다. github에서 코드를 탐색 할 수도 있습니다.

    바이너리 프로토콜을 디버깅하는 동안 나는 hexdump ()도 필요로했다. 분명히 유용하기 때문에 내 솔루션을 PEAR 패키지로 게시하기로 결정했습니다. github에서 코드를 탐색 할 수도 있습니다.

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

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

    mindplays 솔루션 외에도 마지막 라인 및 추가 매개 변수의 프로퍼 렌더링을 지원합니다. 또한이 패키지에는 cmdline의 hexdumps 용 phphd라는 실행 파일이 들어 있습니다. 이것은 Windows 시스템에서 도움이 될 수 있습니다 :)

    @ mindplay.dk : strtr () 아이디어에 감사드립니다. 그것은 이전의 시도보다 약간 빠른 것처럼 보였습니다. 내 버전에 통합. (감소 된 번역 버퍼 사용) ..

    재미있게 보내십시오!

  5. ==============================

    5."기능적"버전 :

    "기능적"버전 :

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

    Ionuţ G. Stan의 의견을 빌리 자면, 마지막 줄은 다음과 같을 것이다.

    }, array_map('dechex', array_map('ord', str_split($s)))));
    
  6. from https://stackoverflow.com/questions/1057572/how-can-i-get-a-hex-dump-of-a-string-in-php by cc-by-sa and MIT license