unpack
函数执行 pack
函数的逆操作:它接收一个字符串并将其扩展为一个值列表。 (在标量上下文中,它只返回第一个产生的值。)
如果省略 EXPR,则解包 $_
字符串。有关此函数的介绍,请参阅 perlpacktut。
字符串被分成由 TEMPLATE 描述的块。每个块被单独转换为一个值。通常,字符串要么是 pack
函数的结果,要么字符串的字符表示某种 C 结构。
TEMPLATE 的格式与 pack
函数中的格式相同。以下是一个执行子字符串的子例程
sub substr {
my ($what, $where, $howmuch) = @_;
unpack("x$where a$howmuch", $what);
}
然后是
sub ordinal { unpack("W",$_[0]); } # same as ord()
除了 pack
函数中允许的字段外,您还可以使用 %<number> 前缀字段,表示您想要获取 <number> 位校验和,而不是项目本身。默认值为 16 位校验和。校验和是通过对扩展值的数字值求和来计算的(对于字符串字段,对 ord($char)
求和;对于位字段,对零和一求和)。
例如,以下代码计算与 System V sum 程序相同的数字
my $checksum = do {
local $/; # slurp!
unpack("%32W*", readline) % 65535;
};
以下代码有效地计算了位向量中设置位的数量
my $setbits = unpack("%32b*", $selectmask);
p
和 P
格式应该谨慎使用。由于 Perl 无法检查传递给 unpack
的值是否对应于有效的内存位置,传递一个未知有效性的指针值可能会导致灾难性的后果。
如果存在更多打包代码,或者字段或组的重复次数大于输入字符串剩余部分允许的次数,则结果将无法确定:重复次数可能会减少,或者 unpack
可能会生成空字符串或零,或者它可能会引发异常。如果输入字符串比模板描述的字符串更长,则该输入字符串的剩余部分将被忽略。
有关更多示例和说明,请参阅 pack
。