我有一个十六进制字符串(长度为48个字符),我希望使用pack函数将其转换为原始字节,以便将其放入Win32矢量字节中。
如何使用Perl执行此操作?
答案 0 :(得分:25)
my $bytes = pack "H*", $hex;
有关详细信息,请参阅perlpacktut。
答案 1 :(得分:6)
步骤如下:
例如:
use strict;
use warnings;
my $string = 'AA55FF0102040810204080';
my @hex = ($string =~ /(..)/g);
my @dec = map { hex($_) } @hex;
my @bytes = map { pack('C', $_) } @dec;
或者,表达得更紧凑:
use strict;
use warnings;
my $string = 'AA55FF0102040810204080';
my @bytes = map { pack('C', hex($_)) } ($string =~ /(..)/g);
答案 2 :(得分:1)
我有字符串:
“61 62 63 64 65 67 69 69 6a
”
我想将其解释为十六进制值,并将其显示为ASCII字符(这些值应该重现字符串“abcdefghij”)。
通常情况下,我会尝试像这样快速写一些东西:
$ echo "61 62 63 64 65 67 69 69 6a" | perl -ne 'print "$_"; print pack("H2 "x10, $_)."\n";'
61 62 63 64 65 67 69 69 6a
a
...然后我想知道,为什么我只回到一个角色:)
首先,让我记下我所拥有的字符串,也可以表示为内存中占用的字节的十六进制值:
$ echo -n "61 62 63 64 65 67 68 69 6a" | hexdump -C
00000000 36 31 20 36 32 20 36 33 20 36 34 20 36 35 20 36 |61 62 63 64 65 6|
00000010 37 20 36 38 20 36 39 20 36 61 |7 68 69 6a|
0000001a
_(注意:基本上,我想将内存中的上述字节值“转换”为输入,如果由hexdump查看,则将这些值转换为以下字节值:
$ echo -n "abcdefghij" | hexdump -C
00000000 61 62 63 64 65 66 67 68 69 6a |abcdefghij|
0000000a
...获取输入十六进制字符串的原始值。 )_
嗯,这个Pack/Unpack Tutorial (AKA How the System Stores Data)对我来说是最有帮助的,正如它提到的那样:
pack函数接受模板字符串和值列表[...]
$rec = pack( "l i Z32 s2", time, $emp_id, $item, $quan, $urgent);
它返回一个标量,其中包含根据模板中指定的格式存储的值列表[...]
$rec
将包含以下内容(第一行为十进制,第二行为十六进制,第三行为适用的字符)。管道字符表示字段边界。Offset Contents (increasing addresses left to right) 0 160 44 19 62| 41 82 3 0| 98 111 120 101 115 32 111 102 A0 2C 13 3E| 29 52 03 00| 62 6f 78 65 73 20 6f 66 | b o x e s o f
也就是说,在我的情况下,$_
是一个单个字符串变量 - 而pack
期望输入一个列表的几个这样的'single'变量(除了格式化模板字符串);并输出一个'单个'变量(但是,它可能是一个相当大的内存块!)。在我的例子中,如果输出'single'变量在内存中的每个字节中包含ASCII代码,那么我就完全设置了(我可以直接打印输出变量,然后)。
因此,为了从$_
字符串中获取变量列表,我可以在空格符号上split
- 但请注意:
$ echo "61 62 63 64 65 67 68 69 6a" | perl -ne 'print "$_"; print pack("H2", split(/ /, $_))."\n";'
61 62 63 64 65 67 68 69 6a
a
......必须指定要pack
ed的元素数量(否则我们只返回一个字符);那么,这些替代方案中的任何一个都有效:
$ echo "61 62 63 64 65 67 68 69 6a" | perl -ne 'print "$_"; print pack("H2"x10, split(/ /, $_))."\n";'
61 62 63 64 65 67 68 69 6a
abcdeghij
$ echo "61 62 63 64 65 67 68 69 6a" | perl -ne 'print "$_"; print pack("(H2)*", split(/ /, $_))."\n";'
61 62 63 64 65 67 68 69 6a
abcdeghij