该字串会分解成 TEMPLATE 里描述的片段。每个片段都独立地转化成一个数值。通常,该字串的字节要么是 pack 的结果,要么代表某种类型的 C 结构。
如果一个域的重复计数比输入字串剩余部分允许的尺寸大,那么重复计数就会被不声不响地缩小。(不过,你通常会在这个地方放一个 * 做重复计数。)如果输入字串比 TEMPLATE 描述的长,那么字串剩余的部分被忽略。
unpack 函数对纯文本数据也很有用,而不仅仅是对二进制数据管用。设想你有一个数据文件,它的内容看起来象下面这样:
1986 Ender's Game Orson Scott Card 1985 Neuromancer William Gibson 1984 Startide Rising David Brin 1983 Foundation's Edge Isaac Asimov 1982 Downbelow Station C. J. Cherryh 1981 The Snow Queen Joan D. Vinge
你不能用 split 来分析出各个域,因为这里没有明显的分隔符。这里的域是由它们的字节偏移量来决定的。因此就算这是一个普通的文本记录,但因为它是固定格式的,所以你就可以用 unpack 把它们分解成数据域:
while (<>) {
($year, $title, $author) = unpack("A4 x A23 A*", $_);
print "$author won ${year}'s Hugo for $title.\n";
}
(我们在这里写成 ${year}'s 的原因是 Perl 会把 $year's 当作 $year::s 看待。)
下面是一个完整的 undecode 程序:
#! /usr/bin/perl
$_ = <> until ($mode, $file) = /^begin\s*(\d*)\s*(\S*)/;
open(OUT, "> $file") if $file ne "";
while (<>) {
last if /^end/;
next if /[a-z]/;
next unless int((((ord() - 32) & 077) + 2) / 3) ==
int (length() / 4);
print OUT unpack "u", $_;
}
chmod oct($mode), $file;
除了那些 pack 里允许的数据域以外,除了各个项自身以外,你还可能在一个数据域前面前缀一个%number 作成一个所有项的简单的 number 位附加校验和。该校验和是通过类加扩展数值的数字值来计算的(对于字串域,求 ord($char) 的和,而对于位域,计算零和一的和)。比如,下面的代码计算和 SysV? sum(1) 相同的数字:
undef $/;
$checksum = unpack ("%32C*", <>) % 65535;
下面的代码高效的计算一个位流里的设置上的位的个数:
$setbits = unpack "%32b*", $selectmask;
下面是一个简单的 BASE64 :
本文来自电脑杂谈,转载请注明本文网址:
http://www.pc-fly.com/a/jisuanjixue/article-28372-25.html
疯了
为什么还会失败
呵呵