PHP 怎么PHP pack unpack

wen PHP项目 1

本文目录导读:

PHP 怎么PHP pack unpack

  1. pack() 函数 - 将数据打包成二进制字符串
  2. unpack() 函数 - 解包二进制字符串
  3. 实用示例
  4. 注意事项
  5. 常用格式组合

在 PHP 中,pack()unpack() 函数用于在二进制数据和 PHP 变量之间进行转换,以下是详细的使用说明:

pack() 函数 - 将数据打包成二进制字符串

基本语法

pack(string $format, mixed ...$values): string

常用格式字符

格式 说明 示例
a NUL 填充字符串 a10 - 10字节字符串
A 空格填充字符串 A10 - 10字节字符串
c 有符号字符(1字节) c
C 无符号字符(1字节) C
s 有符号短整数(2字节) s
S 无符号短整数(2字节) S
n 无符号短整数(大端序) n
v 无符号短整数(小端序) v
i 有符号整数(机器相关) i
I 无符号整数(机器相关) I
l 有符号长整数(4字节) l
L 无符号长整数(4字节) L
N 无符号长整数(大端序,4字节) N
V 无符号长整数(小端序,4字节) V
f 单精度浮点数 f
d 双精度浮点数 d

使用示例

// 1. 基本整数打包
$packed = pack('C', 65);  // 输出: "A" (ASCII 65)
echo bin2hex($packed);     // 输出: 41
// 2. 多个值打包
$packed = pack('C4', 65, 66, 67, 68);  // 打包4个字符
echo $packed;  // 输出: "ABCD"
// 3. 混合类型
$packed = pack('nvc', 0x1234, 0x5678, 0x9A);
// n: 无符号短整数(大端序)
// v: 无符号短整数(小端序)
// c: 有符号字符
echo bin2hex($packed);  // 输出: "123478569a"
// 4. 字符串打包
$packed = pack('a10', 'Hello');
echo strlen($packed);  // 输出: 10 (用null填充)
$packed = pack('A10', 'Hello');
echo strlen($packed);  // 输出: 10 (用空格填充)
// 5. 使用数字重复格式
$packed = pack('C*', 1, 2, 3, 4);  // 打包所有参数

unpack() 函数 - 解包二进制字符串

基本语法

unpack(string $format, string $string): array

使用示例

// 1. 解包单个值
$packed = pack('C', 65);
$result = unpack('Cchar', $packed);
echo $result['char'];  // 输出: 65
// 2. 解包多个值
$packed = pack('C4', 65, 66, 67, 68);
$result = unpack('Ca/Cb/Cc/Cd', $packed);
print_r($result);
// 输出: ['a' => 65, 'b' => 66, 'c' => 67, 'd' => 68]
// 3. 解包整数
$packed = pack('n', 0x1234);
$result = unpack('nint', $packed);
echo $result['int'];  // 输出: 4660 (0x1234)
// 4. 解包浮点数
$packed = pack('f', 3.14);
$result = unpack('ffloat', $packed);
echo $result['float'];  // 输出: 3.14
// 5. 解包字符串
$packed = pack('a10', 'Hello');
$result = unpack('a10str', $packed);
echo rtrim($result['str']);  // 输出: "Hello"
// 6. 重复解包
$packed = pack('C*', 1, 2, 3, 4, 5);
$result = unpack('C5nums', $packed);
print_r($result);
// 输出: ['nums1' => 1, 'nums2' => 2, 'nums3' => 3, 'nums4' => 4, 'nums5' => 5]
// 7. 使用 * 解包所有
$result = unpack('C*', $packed);
print_r($result);
// 输出: [1 => 1, 2 => 2, 3 => 3, 4 => 4, 5 => 5]

实用示例

创建二进制文件格式

// 创建一个简单的二进制文件
function writeBinaryFile($filename, $data) {
    // 写入文件头:魔数(2字节) + 版本号(2字节) + 文件大小(4字节)
    $header = pack('nnV', 0x4D41, 1, strlen($data));
    // 写入数据
    file_put_contents($filename, $header . $data);
}
// 读取二进制文件
function readBinaryFile($filename) {
    $content = file_get_contents($filename);
    // 解析文件头
    $header = unpack('nmagic/nversion/Vsize', substr($content, 0, 8));
    // 读取数据
    $data = substr($content, 8, $header['size']);
    return [
        'magic' => $header['magic'],
        'version' => $header['version'],
        'size' => $header['size'],
        'data' => $data
    ];
}

网络协议通信

// 创建网络消息
function createMessage($type, $content) {
    $payload = pack('n', $type) . $content;
    $length = strlen($payload);
    return pack('N', $length) . $payload;
}
// 解析网络消息
function parseMessage($buffer) {
    if (strlen($buffer) < 4) {
        return null;
    }
    $length = unpack('Nlen', substr($buffer, 0, 4))['len'];
    if (strlen($buffer) < 4 + $length) {
        return null;
    }
    $type = unpack('ntype', substr($buffer, 4, 2))['type'];
    $content = substr($buffer, 6, $length - 2);
    return [
        'type' => $type,
        'content' => $content
    ];
}

注意事项

  1. 字节序问题:注意区分大端序(network byte order)和小端序(little-endian)
  2. 数据对齐:某些系统可能有字节对齐要求
  3. 类型范围:确保数据在类型允许的范围内
  4. 字符串处理aA 格式的区别在于填充字符

常用格式组合

// 常见二进制协议格式
$data = pack(
    'nCVCV',  // 格式:小端序短整数 + 字符 + 无符号整数 + 字符 + 无符号整数
    0x1234,   // 魔数
    1,        // 版本
    100,      // 数据1
    2,        // 状态
    200       // 数据2
);
// 解包上述数据
$result = unpack('nmagic/Cversion/Vdata1/Cstatus/Vdata2', $data);

pack/unpack 在处理二进制数据时非常强大,适用于文件格式解析、网络协议实现、加密算法等领域。

抱歉,评论功能暂时关闭!