Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Recreating a binary file from hex representation

by choedebeck (Beadle)
on Jul 07, 2006 at 15:47 UTC ( [id://559814]=perlquestion: print w/replies, xml ) Need Help??

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

I have been trying to convert a binary file to hex representation, and then taking that hex representation and recreating the binary file. I have been able to read in a binary file as hex using the following code
my $buffer; open INFILE, "test.bin" or die "Can't open test.bin for reading: $!\n" +; open OUTFILE, ">test.bin" or die "Can't open test.bin for writing: $!\ +n"; select OUTFILE; binmode INFILE; while (read(INFILE, $buffer, 1) and printf("%X", ord($buffer))){}; print "\n";
But I am having trouble taking this hex representation and recreating the binary file with it. Here is the script I have currently that is not working
my $buffer; open INFILE, "test.text" or die "Can't open test.txt for reading: $!\n +"; open OUTFILE, ">test_updated.bin" or die "Can't open test_updated.bin +for writing: $!\n"; binmode OUTFILE; my $line = <INFILE>; chomp $line; my @list = split //, $line; my $hex_value; my $i =1; foreach my $character (@list) { if($i%2 == 0) { $hex_value .= $character; syswrite OUTFILE, hex($hex_value); } elsif($i%2 == 1) { $hex_value = "0x".$character; } $i++; }
This code just write a bunch of number to the binary file which is not what I want. Anyone have any ideas on what I am doing wrong?

Replies are listed 'Best First'.
Re: Recreating a binary file from hex representation
by davido (Cardinal) on Jul 07, 2006 at 16:05 UTC

    It seems like the whole thing would be easier if you used pack and unpack to convert between hex and some binary representation. perlpacktut is helpful in understanding pack and unpack.


    Dave

Re: Recreating a binary file from hex representation
by shmem (Chancellor) on Jul 07, 2006 at 17:42 UTC
    You should use pack and unpack as was pointed out already, but the error in your script is here:
    printf("%X", ord($buffer))
    One Byte can be 0 to FF in hex. If you have a stream of hex characters, how can you know you have 1A (26 in decimal) or two numbers, 1 and 10?

    say

    printf("%02X", ord($buffer))
    to make shure each byte is represented by 2 chars (e.g. 0A for decimal 10 instead of just A). Converting back you have to read 2 Bytes each time.

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: Recreating a binary file from hex representation
by planetscape (Chancellor) on Jul 07, 2006 at 17:40 UTC

    Or be lazy and use a module that does base64? ;-)

    HTH,

    planetscape
Re: Recreating a binary file from hex representation
by wazoox (Prior) on Jul 07, 2006 at 21:46 UTC
    I'm working on a set of modules that read and write binary files. It's quite long, but here are the interesting parts :
    First, I store the data in a hash: Then there are a couple of subs to manage this, here is the important part for writing :
    sub validfields { return $_validfields } sub _packdata { #****m* DataFile/_packdata # USAGE # $file->_packdata() # sérialise pour pack() tous les records # d'un fichier #*** my $self = shift ; my @stringrecords ; foreach my $record_ref ( @{ $self->{records} } ) { # il faut déréférencer l'objet record avant de l'appeler my $recdata = $self->_serialize_fields( $$record_ref->getdata( +) ); push @stringrecords, $recdata if $recdata ; } @stringrecords ? return join ( '', @stringrecords ) : return } sub _serialize_fields { #****m* DataFile/serialize_fields # USAGE # $file->_serialize_fields( $data_href ) # sérialise les données d'un record #*** my $self = shift ; my $data = shift ; my $output = ''; my $allfields = $self->validfields() ; # on itère sur tous les champs possibles foreach my $k ( keys %$allfields ) { # on insère la longueur en dernier next if $k eq 'LENGTH' ; my $value ; ( exists $data->{$k} ) ? ( $value = $data->{$k} ) : ( $value = + $allfields->{$k}{default} ) ; # le champ COLLATE est le seul qui soit un BYTE # les champs "noms courts" doivent contenir 0x01 # la longueur est corrigée de la longueur du format $output .= pack( $allfields->{$k}{format}. ( $allfields->{$k}{ +length} - length($allfields->{$k}{format}) + 1 ), $value ); } # on insère la longueur du champ au début my $datalength = length($output) + 5; $output = pack( "A5",$datalength ) . $output ; print $output ; return $output }
    Hope this helps.
Re: Recreating a binary file from hex representation
by TedPride (Priest) on Jul 07, 2006 at 16:10 UTC
    Or you could go the kloodge route and create a hex-to-character lookup:
    @chars = (0..9, 'A'..'Z'); for (0..255) { $hex{$chars[int($_ / 16)].$chars[$_ % 16]} = chr($_); }
    Just feed it two hex characters and it returns the regular string character.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (3)
As of 2024-04-25 05:35 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found