Perl程序将二进制转换为ascii

时间:2016-02-03 12:22:18

标签: perl

我必须使用Perl将二进制文件转换为ascii值,我必须进一步解析它以进行处理。我做了一些研究,发现下面的代码。我可以让它完美地工作,但不完全理解代码。有人可以分解并逐行解释吗? P.S:我理解大多数行,但我特别关注实际二进制转换为ascii的部分。感谢。

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)
}

2 个答案:

答案 0 :(得分:2)

我认为您的问题出在unpack电话上。我稍微改了一下

my @x = unpack '(H2)*', $buf

格式说明符(H2)*表示将第二个参数中字符串的每个字节转换为两位十六进制数。 *只是意味着转换字符串

中的字节数

这将适合您

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

输出

这里倾销自己

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

答案 1 :(得分:1)

不使用Binary,也没有转换为ASCII。

程序显示文件每个字节的十六进制表示。其核心是unpack 'H2', $byte,它返回一个字节的十六进制表示。

它还显示这些字节的ASCII表示。该程序不需要进行任何转换即可。这些字节只是发送到终端,然后将它们映射到字形。