cosmofield has asked for the wisdom of the Perl Monks concerning the following question:

Hello, I'm new here

I could need some help to improve one of my subs, I've done some "google" but apparently to no awail.

The sub needs to make a PNG-file based on contents in a hash specified by one input used both as the hash key and the resulting filename.

My question is however if there's a more efficient way to write a hex string as binary to a file? Feedback appreciated.

sub writeAnImage { my $hashCode = $_[0]; my %pngData = ( 'blank', '89504e470d0a1a0a0000000d49484452000000320000005a0803000000 +cd46f5b400000003504c5445efefefec97ba8d0000001b494441545885edc1010d000 +000c2a0f74f6d0f0714000000003f0611ee00013060c47e0000000049454e44ae4260 +82' ); my $dataString = ""; my $twoHex = ""; my $dataLength = 0; my $byteCounter = 0; # if ($hashCode) { if ($pngData{$hashCode}) { $dataString = $pngData{$hashCode}; $dataLength = length($dataString); open(MyPNG, ">$hashCode") or die("Write Error: $hashCode"); binmode(MyPNG); for ($byteCounter = 0; $byteCounter <= $dataLength; $byteCounter + += 2) { $twoHex = substr($dataString, $byteCounter, 2); print MyPNG chr(hex($twoHex)); } close(MyPNG); } else { print "No such code in the hash ($hashCode)\n"; } } else { print "No code specified\n"; } }

Replies are listed 'Best First'.
Re: What is the best method to print hex string in bin-file?
by jmcnamara (Monsignor) on Aug 31, 2010 at 13:24 UTC

    You can just use pack 'H*' on the string as follows:
    my $bin_str = pack 'H*', $hex_st;
    Or in the case of your example, something like this:
    ... if ( $pngData{$hashCode} ) { open MyPNG, '>', $hashCode or die "Write Error: $hashCode: +$!\n"; binmode MyPNG; print MyPNG pack 'H*', $pngData{$hashCode}; close MyPNG; } ...
    I often use this with qw() to keep the binary data nicely formatted:
    my $bin_str = pack 'H*', join '', qw( 18 00 1B 00 21 00 00 01 0B 00 00 00 01 00 00 00 21 00 00 01 0B 00 00 00 01 00 00 00 18 00 1B 00 00 00 00 0D 3B 00 00 00 00 04 00 00 00 02 00 FF 00 01 0B 00 00 00 01 00 00 00 );

    --
    John.