Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Reconstruct binary data saved with unpack("H*", $b)

by andreas1234567 (Vicar)
on Jul 27, 2011 at 12:10 UTC ( [id://917006]=perlquestion: print w/replies, xml ) Need Help??

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

Honorable Monks,

An application reads binary data from an external system, and saves it using $h = unpack("H*", $b). If I try to reconstruct the binary data with $b = pack("H*", $h), the binary data will sometimes have a trailing null byte. Is it possible to make sure the binary data as it were (i.e. never add the null byte)?

A little code sample to illustrate the problem indicates that is works when input length is even only:
$ cat pack.t use strict; use warnings; use Test::More qw /no_plan/; my @arr = (0 .. 9, 'a' .. 'f'); my $hexdata = q{}; while (@arr) { $hexdata .= shift @arr; my $binary_data = pack("H*", $hexdata); cmp_ok(unpack('H*', $binary_data), 'eq', $hexdata); } __END__ $ perl pack.t not ok 1 # Failed test at pack.t line 11. # got: '00' # expected: '0' ok 2 not ok 3 # Failed test at pack.t line 11. # got: '0120' # expected: '012' ok 4 not ok 5 # Failed test at pack.t line 11. # got: '012340' # expected: '01234' ok 6 not ok 7 # Failed test at pack.t line 11. # got: '01234560' # expected: '0123456' ok 8 not ok 9 # Failed test at pack.t line 11. # got: '0123456780' # expected: '012345678' ok 10 not ok 11 # Failed test at pack.t line 11. # got: '0123456789a0' # expected: '0123456789a' ok 12 not ok 13 # Failed test at pack.t line 11. # got: '0123456789abc0' # expected: '0123456789abc' ok 14 not ok 15 # Failed test at pack.t line 11. # got: '0123456789abcde0' # expected: '0123456789abcde' ok 16 1..16 # Looks like you failed 8 tests of 16.
--
No matter how great and destructive your problems may seem now, remember, you've probably only seen the tip of them. [1]

Replies are listed 'Best First'.
Re: Reconstruct binary data saved with unpack("H*", $b)
by Anonymous Monk on Jul 27, 2011 at 12:41 UTC
    I think the solution is to use u template (uuencoding)

    The problem with your sample data is it doesn't come in pairs -- this is where the null is coming from, its padding -- H* demands pairs

Re: Reconstruct binary data saved with unpack("H*", $b)
by ikegami (Patriarch) on Jul 27, 2011 at 19:27 UTC

    Unless your ok with just using chop on the result — at which point it will only work if the input length is odd — it is impossible to recreate your original data since multiple inputs encode identically.

    $ perl -e'print pack "H*", "abc";' | od -t x1 0000000 ab c0 0000002 $ perl -e'print pack "H*", "abc0";' | od -t x1 0000000 ab c0 0000002

    If you don't care about preserving leading zeroes, you can use

    my $bin = pack("H*", ( length($hex) % 2 ? '0' : '' ).$hex); ... ( my $hex = unpack('H*', $bin) ) =~ s/^0+(?!\z)//;

    If you don't care about preserving leading zeroes, you can use

    my $bin = pack("H*", "".reverse $hex); ... ( my $hex = reverse unpack('H*', $bin) ) =~ s/^0+(?!\z)//;

    If you do care about preserving leading zeroes, you can use

    my $bin = pack("NH*", length($hex), $hex) ... my ($length, $hex) = unpack('NH*', $bin); substr($hex, $length, length($hex), '');

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://917006]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (2)
As of 2024-04-24 13:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found