我真的很困惑perl的打包和解包定义.以下是perl.doc.org的摘录
pack函数将值转换为包含根据给定规范的表示的字节序列,即所谓的"模板"参数.unpack是相反的过程,从字节串的内容中导出一些值.
因此我认为pack需要人类可读的东西(例如A)并将其转换为二进制格式.我这个解释错了吗?
所以这就是我的解释,但是然后同样的文件会立即进行这个例子,这使我的理解正好相反.
my( $hex ) = unpack( 'H*', $mem );
print "$hex\n";
Run Code Online (Sandbox Code Playgroud)
我错过了什么?
该pack函数将一个或多个事物放在一个字符串中.它以一种可以在其他程序中可靠地解压缩的方式将事物表示为八位字节(字节).那个节目可能很遥远(就像远处火星的距离).如果它以人类可读或不可读的方式开始并不重要.这不是重点.
考虑一些任务,其中您的数字ID最多约为65,000,字符串最多可包含六个字符.
print pack 'S A6', 137, $ARGV[0];
Run Code Online (Sandbox Code Playgroud)
如果在运行时通过十六进制转储器运行它,则更容易看到它正在做什么:
$ perl pack.pl Snoopy | hexdump -C
00000000 89 00 53 6e 6f 6f 70 79 |..Snoopy|
Run Code Online (Sandbox Code Playgroud)
第一列计算输出中的位置,因此忽略它.然后前两个八位字节表示S(短,'字',无论什么,但两个八位字节)格式.我给它编号137,它存储为0x8900.然后它在接下来的六个八位字节中存储了"史努比".
现在尝试使用较短的名称:
$ perl test.pl Linus | hexdump -C
00000000 89 00 4c 69 6e 75 73 20 |..Linus |
Run Code Online (Sandbox Code Playgroud)
现在最后有一个空格字符(0x20).打包数据仍有六个八位字节.尝试使用更长的名称:
$ perl test.pl 'Peppermint Patty' | hexdump -C
00000000 89 00 50 65 70 70 65 72 |..Pepper|
Run Code Online (Sandbox Code Playgroud)
现在它截断字符串以适应六个可用空格.
考虑一下你通过套接字或其他方式与其他东西进行通信的情况.另一方面的事情知道它将获得八个八位字节.它也知道前两个将是短的,接下来的六个将是名称.假设对方存储了它$tidy_little_package.它通过解压缩得到单独的值:
my( $id, $name ) = unpack 'S A6', $tidy_little_package;
Run Code Online (Sandbox Code Playgroud)
这就是主意.您可以用完全可逆的二进制格式表示不同类型的许多值.您可以将打包的字符串发送到需要使用的位置.
我pack在学习Perl和Programming Perl中有更多的例子.