在 PHP 中,pack() 和 unpack() 函数常用于处理二进制数据,尤其适合在网络通信、文件读写、数据编码等需要精确控制字节的场景中使用。本文将详细讲解这两个函数的用法,并附上完整的格式码对照表,帮助你更高效地处理二进制数据。
pack():将数据打包成二进制字符串。
unpack():将二进制字符串解包成 PHP 数组。
两者使用格式码(format code)来定义数据的结构,这些格式码决定了如何编码/解码数据的方式。
$data = pack("C*", 72, 101, 108, 108, 111); // 将 ASCII 码转换成字符串 "Hello"
echo $data; // 输出: Hello
语法:
string pack(string $format, mixed $values...)
$data = "Hello";
$result = unpack("C*", $data);
print_r($result);
输出:
Array
(
[1] => 72
[2] => 101
[3] => 108
[4] => 108
[5] => 111
)
语法:
array unpack(string $format, string $data, int $offset = 0)
格式码 | 说明 | 字节长度 | 大小端 |
---|---|---|---|
a | NUL 填充字符串(不去除 NUL) | 指定长度 | 无 |
A | 空格填充字符串(会去除尾部空格) | 指定长度 | 无 |
h | 十六进制字符串,每个字符表示 4 bits | 每两位 = 1 byte | 无 |
H | 大写十六进制,每个字符表示 4 bits | 每两位 = 1 byte | 无 |
c | 有符号字符(8 位) | 1 字节 | 无 |
C | 无符号字符(8 位) | 1 字节 | 无 |
s | 有符号短整型(16 位) | 2 字节 | 主机字节序 |
S | 无符号短整型(16 位) | 2 字节 | 主机字节序 |
n | 无符号短整型(16 位),网络字节序 | 2 字节 | 大端 |
v | 无符号短整型(16 位),小端字节序 | 2 字节 | 小端 |
i | 有符号整数(机器相关) | 4 字节或 8 字节 | 主机字节序 |
I | 无符号整数(机器相关) | 4 字节或 8 字节 | 主机字节序 |
l | 有符号长整型(32 位) | 4 字节 | 主机字节序 |
L | 无符号长整型(32 位) | 4 字节 | 主机字节序 |
N | 无符号长整型(32 位),网络字节序 | 4 字节 | 大端 |
V | 无符号长整型(32 位),小端字节序 | 4 字节 | 小端 |
f | 单精度浮点数(32 位) | 4 字节 | 主机字节序 |
d | 双精度浮点数(64 位) | 8 字节 | 主机字节序 |
x | 填充字节(跳过 1 个字节) | 1 字节 | 无 |
X | 回退 1 个字节 | 1 字节 | 无 |
@ | 设置绝对位置(跳过/回退到某位置) | 可变 | 无 |
$ip = "192.168.1.1";
$packed = pack("C4", ...explode('.', $ip));
echo bin2hex($packed); // 输出 c0a80101
$unpacked = unpack("C4", $packed);
echo implode('.', $unpacked); // 输出 192.168.1.1
$binary = file_get_contents("https://m66.net/example/file.bin");
$header = unpack("a4signature/Nsize", $binary);
print_r($header);
格式码可以用数量修饰,例如:
C4:表示 4 个无符号字符
A10:表示 10 个字符的空格填充字符串
@8:跳转到第 8 字节位置
你也可以使用 * 表示尽可能多地读取:
$data = unpack("C*", "Hello"); // 读取所有字节
PHP 的 pack() 和 unpack() 是强大的二进制处理工具,熟悉其格式码和用法可以帮助你更灵活地处理底层数据。无论是在解析协议、存储结构化数据,还是构建高效网络通信协议,这两个函数都是非常实用的工具。
格式码虽然多,但掌握常用的几种(如 C, n, N, f, d)即可满足大多数需求。建议在开发中配合 bin2hex() 和 hex2bin() 一起使用,调试更方便。