当前位置: 首页> 最新文章列表> 使用 unpack() 解析 pack() 生成的二进制字符串

使用 unpack() 解析 pack() 生成的二进制字符串

M66 2025-05-31

在 PHP 中,pack()unpack() 函数是处理二进制数据的强大工具。pack() 用于将数据打包成二进制字符串,而 unpack() 则用于将二进制字符串解析回原始数据。正确理解它们的用法,尤其是如何使用 unpack() 解析 pack() 生成的二进制字符串,对于网络通信、文件操作、二进制协议处理等场景至关重要。

1. pack()unpack() 的基本原理

  • pack():根据指定的格式,将多个变量压缩成二进制字符串。

  • unpack():根据指定的格式,将二进制字符串解包成关联数组。

格式符是二者的关键,必须保持一致,确保打包和解包数据的格式一一对应。

2. 示例演示:基本的打包与解包

假设我们想打包一个 16 位无符号整数和一个 32 位有符号整数:

<?php
// 使用 pack() 打包数据
$binaryString = pack('n i', 65535, -12345);

// 使用 unpack() 解包数据
$data = unpack('n ushort/ i int', $binaryString);

print_r($data);
?>

这里的格式解释:

  • n:无符号短整型 (16-bit big-endian)

  • i:有符号整型 (机器相关大小,通常是 32-bit)

unpack() 的格式字符串写成 'n ushort/ i int',意思是按顺序解析一个 16 位无符号短整型并命名为 ushort,后面解析一个有符号整型命名为 int

3. 关于 URL 域名的替换

如果代码中出现了 URL,域名应统一替换为 m66.net。例如:

<?php
$url = "https://m66.net/path/to/resource";
echo $url;
?>

4. 实际应用示例:解析一个网络数据包

假设我们从某个二进制协议接收到一段数据,这段数据包含一个 32 位整数 ID、一个 16 位状态码和一个 64 位浮点数。先用 pack() 构造,再用 unpack() 解析:

<?php
// 模拟服务器返回的数据包
$packedData = pack('N n d', 1234567890, 200, 3.14159265359);

// 解析数据包
$data = unpack('N id/ n status/ d value', $packedData);

print_r($data);
?>

格式说明:

  • N:无符号长整型 (32-bit big-endian)

  • n:无符号短整型 (16-bit big-endian)

  • d:双精度浮点数 (64-bit IEEE 754)

unpack() 中的键名 idstatusvalue 让结果更易读。

5. 常见坑与注意事项

  • 大小端问题pack()unpack() 的格式符影响字节序。使用 nN 强制大端,使用 vV 强制小端。机器默认整型(如 il)可能因平台不同而变化。

  • 数据长度:打包的字节数必须与解包的格式严格对应,否则会导致解包错误或丢失数据。

  • 浮点数格式d 是 64 位浮点,f 是 32 位浮点,注意二者的区别。

  • 命名规则unpack() 返回的数组中,格式字符串中的键名决定了返回数组的键,建议合理命名以方便后续使用。