HiveBrain v1.2.0
Get Started
← Back to all entries
snippetphpMinor

PHP function to create a Hex dump

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
dumpcreatephpfunctionhex

Problem

I was needing to provide the hex-dump of a code, but I needed to create my own. And, for fun, I decided to do it.

`function hex_dump( $value )
{
$start_time = microtime(true);

switch( gettype( $value ) )
{
case 'string':

$lines = array_map(
function( $line ){
return array_map(
function( $char ){
return str_pad( dechex( ord( $char ) ), 2, 0, STR_PAD_LEFT );
},
str_split( $line )
);
},
str_split( $value, 16 )
);
break;

case 'double':
case 'integer':

$lines = array(
array_map(
function( $digits ){
return str_pad( $digits, 2, 0, STR_PAD_LEFT );
},
str_split( dechex( $value ), 2 )
)
);
break;

case 'array':

$lines =
array_map(
function( $chunk ){
return array_map(
function( $item ){
switch( gettype( $item ) )
{
case 'double':
case 'integer':
return str_pad( dechex( $item & 255 ), 2, 0, STR_PAD_LEFT );
case 'string':
return str_pad( dechex( ord( $item ) ), 2, 0, STR_PAD_LEFT );
default:
return '--';
}
},
$chun

Solution

Converting to hex and outputting the hex dump are two separate concerns. You should have another function (named to_hex or something similar) that handles the actual converting. You might even want a third one for formatting if you want to truly separate concerns.

Once you have this to_hex function, the array case should call to_hex recursively with each element rather than repeating logic (you asked about DRY -- your current approach is very unDRY with regards to this). As a bonus, it will then automatically support nested arrays.

If you care (a lot) about performance, your string case is very non-optimal. str_split creates an array each time it's called which means that you're copying data for no real reason. If you're interested in performance, you should loop over the string in place (your array case has a similar flaw).

Really I doubt performance matters this much, but it seemed worth mentioning given the timing code you have :).

If unsupported types cause a false return, I would expect the array case to act similarly if it comes across an element of unhandled type.

Likewise, I would expect the array case to actually handle integers, not just the first byte of integers.

Don't be afraid to use intermediate variables. Some of your lines are just straight up beastly, especially the output parts. I also find it clearer to have multiple echo calls rather than stringing together super long echos:

echo ...;
echo ...;
echo ...;


vs

echo ..., ..., ...;


Functions should very rarely actually output. Instead, functions should return their values and the caller should output the return if desired. Imagine if you wanted to write one of these hex dumps to a file. Currently you'd have to do it with some nasty output buffering or stdout redirection (which then gets complicated if you want to have certain things actually echo out). It's a bit weird to think about it like this at first, but generating data and outputting data are two very different concerns and should thus not typically be handled by the same function. There are of course times when it's necessary or desirable for performance or usability reasons to directly output, but I don't think this is one of them.

Code Snippets

echo ...;
echo ...;
echo ...;
echo ..., ..., ...;

Context

StackExchange Code Review Q#92241, answer score: 2

Revisions (0)

No revisions yet.