简体   繁体   中英

Perl program to convert binary to ascii

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? PS: 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)
}

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";
}

output

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";.}  ]

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM