Perl程序将二进制转换为ascii
Posted
技术标签:
【中文标题】Perl程序将二进制转换为ascii【英文标题】:Perl program to convert binary to ascii 【发布时间】:2016-02-03 12:22:18 【问题描述】:我必须使用 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$formx0: %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)
【问题讨论】:
阅读“perldoc pack”和“perldoc unpack”。它的语法本身就是一种语言 When would you use unpack('h*' ...) or pack('h*' ...)?的可能重复 那个程序似乎有问题。print $fw ...;
应该是 printf ...;
。
但是这个程序非常适合我,并且达到了我的目标。我可以使用此脚本将二进制转换为十六进制转储样式格式。
【参考方案1】:
我认为您的问题与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";. ]
【讨论】:
感谢您的回答。在while循环中,你能一步一步解释发生了什么吗? @srib:解决像 cmets 这样的广泛问题是不合适的。没有什么不是标准 Perl,所以你应该阅读the documentation @Borodin 这种态度让 Perl 社区每天都在变小。虽然您的回答是正确的,并且您给出了一个有用的答案,但在您的代码行中放置教学/解释性 cmets 以帮助知识很少的人从中学习,甚至当他明确要求帮助理解它时,这将是一个更友好的方式来帮助他和其他人。只是我的观点。是的,我知道这是一个四年前的回应,但仍然如此。【参考方案2】:不使用二进制,也没有转换为 ASCII。
程序显示文件每个字节的十六进制表示。它的核心是unpack 'H2', $byte
,它返回一个字节的十六进制表示。
它还显示这些字节的 ASCII 表示。该程序不需要做任何转换来做到这一点。字节被简单地发送到将它们映射到字形的终端。
【讨论】:
以上是关于Perl程序将二进制转换为ascii的主要内容,如果未能解决你的问题,请参考以下文章