Спустя годы, но в случае, если другие тоже ищут это, я позволил себе изменить код mindplay.dk, чтобы он принимал различные опции и моделировал вывод файла BSD hexdump -C:
<code>/**
* 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 = '.'
*
*
* @param string $ string
* @param array $ options
* @param string | array
* /
function hex_dump ($ string, array $ options = null) {
if (! is_scalar ($ string)) {
бросить новое InvalidArgumentException («аргумент $ 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']: '.'; # отступы для нечитаемых символов
$ 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 как $ 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;
}
и это шестнадцатеричный дамп маленького файла:
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);
}
}