Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Perl 您什么时候会使用解包(unpack)或打包(pack)?_Perl_Hex_Pack_Unpack - Fatal编程技术网

Perl 您什么时候会使用解包(unpack)或打包(pack)?

Perl 您什么时候会使用解包(unpack)或打包(pack)?,perl,hex,pack,unpack,Perl,Hex,Pack,Unpack,在Perl中,有两个用于将字节转换为十六进制的模板: h一个十六进制字符串(先是低位Nyble)。 H一个十六进制字符串(首先是高Nyble) 最好用一个例子来说明这一点: use 5.010; # so I can use say my $buf = "\x12\x34\x56\x78"; say unpack('H*', $buf); # prints 12345678 say unpack('h*', $buf); # prints 21436587 如您所见,H是人们在考虑将字节转换

在Perl中,有两个用于将字节转换为十六进制的模板:

h
一个十六进制字符串(先是低位Nyble)。
H
一个十六进制字符串(首先是高Nyble)

最好用一个例子来说明这一点:

use 5.010; # so I can use say
my $buf = "\x12\x34\x56\x78";

say unpack('H*', $buf); # prints 12345678
say unpack('h*', $buf); # prints 21436587
如您所见,
H
是人们在考虑将字节转换为十六进制时通常的意思。那么
h
的目的是什么呢?拉里一定认为有人会用它,否则他不会费心把它包括进去

你能给出一个真实的例子吗?在这个例子中,你实际上想使用
h
而不是
h
pack
unpack
我正在寻找一个具体的例子;如果你知道有一台机器是这样组织字节的,它是什么,你能链接到它的一些文档吗


我可以想到一些可以使用
h
的例子,比如在你不在乎格式是什么的情况下序列化一些数据,只要你能读回,但是
h
同样有用。我正在寻找一个例子,其中
h
h

更有用我认为这在向具有不同终端的机器传输数据或从机器读取数据时很有用。如果某个进程希望以通常在内存中表示的方式接收数据,那么您最好以这种方式发送数据。

两者之间的区别只是与您使用的是大端数据还是小端数据有关。有时,您无法控制数据的源或目标,因此要打包的
H
H
标志将为您提供选项
V
N
是出于同样的原因而存在的。

回想一下在糟糕的ole时代,某些操作系统功能是通过在寄存器上设置高半字节和低半字节并执行中断xx来控制的。例如,INT21访问了许多文件函数。您可以将高半字节设置为驱动器号——谁将拥有超过15个驱动器??低半字节作为该驱动器上的请求功能,等等

是一些旧的CPAN代码,它使用您描述的包来设置寄存器以执行MS-DOS系统调用

哎哟!!!我一点也不想念MS-DOS

--编辑

下面是具体的源代码:下载Perl5.00402forDoS,解压

在Opcode.pm和Opcode.pl文件中,您可以看到
unpack(“h*”,$[0])的用法此处:

sub opset_to_hex ($) {
    return "(invalid opset)" unless verify_opset($_[0]);
    unpack("h*",$_[0]);
}
我并没有一直遵循代码,但我怀疑这是为了从MS-DOS系统调用中恢复信息

在Perl 5.8-8中,建议对目标的持久性进行以下测试:

不同的CPU以不同的方式存储整数和浮点数 顺序(称为endianness)和宽度(32位和64位为 今天最常见)。当程序试图传输时,这会影响程序 从一个CPU体系结构到另一个CPU体系结构的二进制格式的数字, 通常通过网络连接或通过存储 将数字发送到辅助存储,如磁盘文件或磁带

相互冲突的存储顺序使数字变得一塌糊涂。如果 little-endian主机(英特尔,VAX)将
0x12345678
305419896
存储在 decimal),一个大端主机(Motorola、Sparc、PA)将其读取为
0x78563412
2018915346
十进制)。Alpha和MIPS可以是: Digital/Compaq在little endian模式下使用它们;SGI/Cray用途 他们在大端模式。为了避免网络(套接字)中出现此问题 连接使用
pack
unpack
格式
n
n
,即 “网络”订单。这些保证是便携式的


从perl 5.8.5开始,您还可以使用
我认为它不包含endianess,因为这是一个字节内的nybles。字节仍然以相同的顺序处理。混合或中间端也碰巧存在。你能给出这样一台机器的具体例子吗?根据维基百科,PDP-11就是一个例子。这几天没人会在意,真的,但还是。显然,在一些ARM机器上也有类似的数据。此外,您似乎还假设您处理的数据始终是字节对齐的。@cjm:当人们说“endianness”时,他们通常谈论的是字节顺序,但实际上,这个主题更广泛,可以包括nybble,甚至位顺序。最终,内部表示依赖于硬件,可以是设计者提出的任何疯狂方案。我不认为endianess包含在内,因为这是一个字节内的Nybles。字节仍按相同的顺序处理。正如
rafl
所提到的,这些字节只是偶尔出现的情况,在这种情况下,您必须处理“有趣”的数据,想想遗留系统和代码使用的深奥的、文档不全的二进制文件格式
pack
,但是它既不使用
h
也不使用
h
,只使用
s
c
   print unpack("h*", pack("s2", 1, 2)), "\n";
   # '10002000' on e.g. Intel x86 or Alpha 21064 in little-endian mode
   # '00100020' on e.g. Motorola 68040
   $is_big_endian    = unpack("h*", pack("s", 1)) =~ /01/;
   $is_little_endian = unpack("h*", pack("s", 1)) =~ /^1/;