Perl pack 函数
最后修改于 2025 年 4 月 4 日
Perl 的 pack
函数将数据转换为二进制表示。它对于二进制文件 I/O、网络协议和数据序列化至关重要。
pack
使用模板字符串指定数据格式。它根据模板返回包含打包数据的二进制字符串。对应的函数是用于反向操作的 unpack
。
基本 pack 用法
pack
最简单的用法是将数字转换为二进制字符串。
#!/usr/bin/perl use strict; use warnings; use v5.34.0; my $packed = pack("C", 65); print "Packed ASCII 'A': ", unpack("H*", $packed), "\n"; my $packed_short = pack("s", 12345); print "Packed short: ", unpack("H*", $packed_short), "\n";
我们演示了打包一个字符和一个短整数。“C”模板打包无符号字符,“s”打包短整数。我们使用 unpack
来显示十六进制表示。
$ ./basic.pl Packed ASCII 'A': 41 Packed short: 3930
打包多个值
pack
可以将多个值合并到一个二进制字符串中。
#!/usr/bin/perl use strict; use warnings; use v5.34.0; my $data = pack("CCCC", 65, 66, 67, 68); print "Packed ABCD: ", unpack("H*", $data), "\n"; my $mixed = pack("CS", 65, 12345); print "Packed mixed: ", unpack("H*", $mixed), "\n";
此示例打包了四个字符和一种混合格式。模板字符串指定了要打包的数据的顺序和类型。每个格式字符处理参数列表中的一个值。
$ ./multiple.pl Packed ABCD: 41424344 Packed mixed: 413930
字符串打包
pack
可以处理具有各种格式选项的字符串。
#!/usr/bin/perl use strict; use warnings; use v5.34.0; my $str = "Perl"; my $packed_str = pack("a4", $str); print "Packed string: ", unpack("H*", $packed_str), "\n"; my $null_terminated = pack("Z*", $str); print "Null-terminated: ", unpack("H*", $null_terminated), "\n";
我们演示了使用“a”(空格填充)和“Z”(null 终止)格式的 ASCII 字符串打包。星号 (*) 允许可变长度字符串。
$ ./string.pl Packed string: 5065726c Null-terminated: 5065726c00
网络字节序
网络协议通常需要特定的字节序。
#!/usr/bin/perl use strict; use warnings; use v5.34.0; my $port = 80; my $ip = "192.168.1.1"; my $packed_port = pack("n", $port); my @octets = split /\./, $ip; my $packed_ip = pack("C4", @octets); print "Packed port: ", unpack("H*", $packed_port), "\n"; print "Packed IP: ", unpack("H*", $packed_ip), "\n";
这显示了网络字节序(“n”表示大端短整数)和 IP 地址打包。网络协议通常使用大端字节序。
$ ./network.pl Packed port: 0050 Packed IP: c0a80101
二进制文件写入
pack
对于写入二进制文件至关重要。
#!/usr/bin/perl use strict; use warnings; use v5.34.0; my $filename = "data.bin"; open(my $fh, '>', $filename) or die "Cannot open file: $!"; my $header = pack("a4LL", "DATA", 1, 12345); print $fh $header; close($fh); print "Wrote binary file '$filename'\n";
我们创建了一个带有标题结构的简单二进制文件。模板“a4LL”打包一个 4 字节字符串,后跟两个无符号长整数。这在二进制文件格式中很常见。
$ ./file.pl Wrote binary file 'data.bin'
浮点数
pack
可以处理各种格式的浮点数。
#!/usr/bin/perl use strict; use warnings; use v5.34.0; my $float = 3.14159; my $packed_float = pack("f", $float); my $packed_double = pack("d", $float); print "Packed float: ", unpack("H*", $packed_float), "\n"; print "Packed double: ", unpack("H*", $packed_double), "\n";
这演示了将浮点数打包为 32 位(“f”)和 64 位(“d”)值。确切的十六进制输出取决于您系统的浮点表示。
$ ./float.pl Packed float: d00f4940 Packed double: 6e861bf0f9210940
复杂数据结构
pack
可以创建具有重复的复杂二进制结构。
#!/usr/bin/perl use strict; use warnings; use v5.34.0; my @values = (1..5); my $packed = pack("L5", @values); print "Packed array: ", unpack("H*", $packed), "\n"; my $struct = pack("LSZ8", 12345, 3.14, "Perl"); print "Packed struct: ", unpack("H*", $struct), "\n";
我们打包了一个长整数数组和一个混合结构。“L5”中的“5”将长整数格式重复了五次。复杂的二进制协议通常使用此类结构。
$ ./complex.pl Packed array: 0100000002000000030000000400000005000000 Packed struct: 39300000c3f54840Perl00
最佳实践
- 使用显式格式: 明确指定字节序和大小。
- 验证输入: 确保数据符合目标格式。
- 记录模板: 注释复杂的格式字符串。
- 跨平台测试: 字节序可能因系统而异。
- 与 unpack 结合: 通过 unpack 验证打包的数据。
来源
本教程介绍了 Perl 的 pack
函数,并通过实际示例演示了各种场景下的二进制数据转换。
作者
列出 所有 Perl 教程。