Reputation: 168
I have to convert binary file to ascii values using Perl, which I have to further parse for processing. I did some research and found below code. I can get it to work perfectly but do not understand the code fully. Can anybody please break it down and explain it line by line? P.S: I understand most of the lines, but I am particularly concerned about the part where the actual binary is converted to ascii. Thanks.
foreach $file(@ARGV)
{
$size= -s $file;
my $form= length(sprintf("%x",$size))-1;
++$form unless $form;
print "File: ",$file,"\n";
open (IN,$file);
while (my $rb= read(IN, $buf, 16))
{
my @x= unpack("H2" x $rb, $buf);
$buf=~ s/[\x00-\x1f\x7f-\xff]/./g;
$buf.= ' ' x (16-length($buf));
print $fw ("%0${form}x0: %s [%s]\n"
,$i++,
,sprintf (" %s %s %s %s %s %s %s %s - %s %s %s %s %s %s %s %s", @x)
,$buf);
}
close (IN)
}
Upvotes: 0
Views: 2614
Reputation: 126762
I think your problem is with the unpack
call. I've changed it slightly to this
my @x = unpack '(H2)*', $buf
The format specifier (H2)*
says to convert each byte of the string in the second parameter to a two-digit hex number. The *
just means to convert as many bytes as there are in the string
This will work properly for you
use strict;
use warnings 'all';
use POSIX 'ceil';
for my $file (@ARGV) {
my $size = 16 * ceil( (-s $file) / 16);
my $form = length sprintf '%x', $size-1;
$form ||= 1;
print "File: $file\n";
open my $fh, '<', $file or die $!;
my $i = 0;
while ( my $rb = read $fh, my $buf, 16 ) {
my @x = unpack '(H2)*', $buf;
push @x, ' ' until @x == 16;
$buf =~ tr/\x20-\x7E/./c;
$buf .= ' ' x (16 - length($buf));
printf "%0*x: %s [%s]\n",
$form,
$i++,
sprintf( "%s %s %s %s %s %s %s %s - %s %s %s %s %s %s %s %s", @x ),
$buf;
}
print "\n";
}
Here it is dumping itself
File: E:\Perl\source\hexdump.pl
000: 75 73 65 20 73 74 72 69 - 63 74 3b 0a 75 73 65 20 [use strict;.use ]
001: 77 61 72 6e 69 6e 67 73 - 20 71 77 2f 20 61 6c 6c [warnings qw/ all]
002: 20 46 41 54 41 4c 20 2f - 3b 0a 0a 75 73 65 20 50 [ FATAL /;..use P]
003: 4f 53 49 58 20 27 63 65 - 69 6c 27 3b 0a 0a 40 41 [OSIX 'ceil';..@A]
004: 52 47 56 20 3d 20 24 30 - 3b 0a 0a 66 6f 72 20 6d [RGV = $0;..for m]
005: 79 20 24 66 69 6c 65 20 - 28 40 41 52 47 56 29 20 [y $file (@ARGV) ]
006: 7b 0a 0a 20 20 20 20 6d - 79 20 24 73 69 7a 65 20 [{.. my $size ]
007: 3d 20 31 36 20 2a 20 63 - 65 69 6c 28 20 28 2d 73 [= 16 * ceil( (-s]
008: 20 24 66 69 6c 65 29 20 - 2f 20 31 36 29 3b 0a 0a [ $file) / 16);..]
009: 20 20 20 20 6d 79 20 24 - 66 6f 72 6d 20 3d 20 6c [ my $form = l]
00a: 65 6e 67 74 68 20 73 70 - 72 69 6e 74 66 20 27 25 [ength sprintf '%]
00b: 78 27 2c 20 24 73 69 7a - 65 2d 31 3b 0a 20 20 20 [x', $size-1;. ]
00c: 20 24 66 6f 72 6d 20 7c - 7c 3d 20 31 3b 0a 0a 20 [ $form ||= 1;.. ]
00d: 20 20 20 70 72 69 6e 74 - 20 22 46 69 6c 65 3a 20 [ print "File: ]
00e: 24 66 69 6c 65 5c 6e 22 - 3b 0a 20 20 20 20 6f 70 [$file\n";. op]
00f: 65 6e 20 6d 79 20 24 66 - 68 2c 20 27 3c 27 2c 20 [en my $fh, '<', ]
010: 24 66 69 6c 65 20 6f 72 - 20 64 69 65 20 24 21 3b [$file or die $!;]
011: 0a 0a 20 20 20 20 6d 79 - 20 24 69 20 3d 20 30 3b [.. my $i = 0;]
012: 0a 20 20 20 20 77 68 69 - 6c 65 20 28 20 6d 79 20 [. while ( my ]
013: 24 72 62 20 3d 20 72 65 - 61 64 20 24 66 68 2c 20 [$rb = read $fh, ]
014: 6d 79 20 24 62 75 66 2c - 20 31 36 20 29 20 7b 0a [my $buf, 16 ) {.]
015: 0a 20 20 20 20 20 20 6d - 79 20 40 78 20 3d 20 75 [. my @x = u]
016: 6e 70 61 63 6b 20 27 28 - 48 32 29 2a 27 2c 20 24 [npack '(H2)*', $]
017: 62 75 66 3b 0a 20 20 20 - 20 20 20 70 75 73 68 20 [buf;. push ]
018: 40 78 2c 20 27 20 20 27 - 20 75 6e 74 69 6c 20 40 [@x, ' ' until @]
019: 78 20 3d 3d 20 31 36 3b - 0a 0a 20 20 20 20 20 20 [x == 16;.. ]
01a: 24 62 75 66 20 3d 7e 20 - 74 72 2f 5c 78 32 30 2d [$buf =~ tr/\x20-]
01b: 5c 78 37 45 2f 2e 2f 63 - 3b 0a 0a 20 20 20 20 20 [\x7E/./c;.. ]
01c: 20 24 62 75 66 20 2e 3d - 20 27 20 27 20 78 20 28 [ $buf .= ' ' x (]
01d: 31 36 20 2d 20 6c 65 6e - 67 74 68 28 24 62 75 66 [16 - length($buf]
01e: 29 29 3b 0a 0a 20 20 20 - 20 20 20 70 72 69 6e 74 [));.. print]
01f: 66 20 22 25 30 2a 78 3a - 20 25 73 20 5b 25 73 5d [f "%0*x: %s [%s]]
020: 5c 6e 22 2c 0a 20 20 20 - 20 20 20 20 20 20 20 24 [\n",. $]
021: 66 6f 72 6d 2c 0a 20 20 - 20 20 20 20 20 20 20 20 [form,. ]
022: 24 69 2b 2b 2c 0a 20 20 - 20 20 20 20 20 20 20 20 [$i++,. ]
023: 73 70 72 69 6e 74 66 28 - 20 22 25 73 20 25 73 20 [sprintf( "%s %s ]
024: 25 73 20 25 73 20 20 25 - 73 20 25 73 20 25 73 20 [%s %s %s %s %s ]
025: 25 73 20 2d 20 25 73 20 - 25 73 20 25 73 20 25 73 [%s - %s %s %s %s]
026: 20 20 25 73 20 25 73 20 - 25 73 20 25 73 22 2c 20 [ %s %s %s %s", ]
027: 40 78 20 29 2c 0a 20 20 - 20 20 20 20 20 20 20 20 [@x ),. ]
028: 24 62 75 66 3b 0a 20 20 - 20 20 7d 0a 0a 20 20 20 [$buf;. }.. ]
029: 20 70 72 69 6e 74 20 22 - 5c 6e 22 3b 0a 7d [ print "\n";.} ]
Upvotes: 2
Reputation: 386676
Binary isn't used, and there's no conversion to ASCII.
The program displays the hex representation of each byte of the file. At its core is unpack 'H2', $byte
, which returns the hex representation of a byte.
It also displays the ASCII representation of those bytes. The program does not need to do any conversion to do this. The bytes are simply sent to the terminal which maps them to glyphs.
Upvotes: 1