当前位置: 首页> 最新文章列表> 如何用 hexdump() 查看 pack() 函数打包后的二进制结构?

如何用 hexdump() 查看 pack() 函数打包后的二进制结构?

M66 2025-06-12

在 PHP 中,pack() 函数用于将数据按照指定格式打包成二进制字符串,常用于底层数据处理、网络通信协议、文件格式解析等场景。为了更好地理解和调试 pack() 打包后的二进制数据,通常需要用类似 hexdump 的方式查看其具体的字节结构。

本文将介绍如何在 PHP 中实现一个简单的 hexdump() 函数,并配合 pack() 函数查看打包后的二进制内容。


pack() 函数简介

pack() 函数的语法是:

string pack(string $format, mixed ...$values)
  • $format 指定数据的打包格式,比如 'C' 表示无符号字符(1字节),'n' 表示16位无符号短整数(网络字节序),'V' 表示32位无符号长整数(小端字节序)等。

  • $values 是要打包的值列表。

例如:

$bin = pack('Cnv', 0x12, 0x3456, 0x789a);

这条语句会生成一个二进制字符串,其中依次包含:

  • 1 字节:0x12

  • 2 字节(网络序,big-endian):0x3456

  • 2 字节(小端序,little-endian):0x789a


自定义 hexdump() 函数

下面是一个简单的 hexdump() 函数,用来将二进制字符串按字节输出十六进制表示,并附带对应的 ASCII 字符:

function hexdump(string $data): void {
    $len = strlen($data);
    $offset = 0;
    while ($offset < $len) {
        // 每行显示16字节
        $chunk = substr($data, $offset, 16);
        $hex = '';
        $ascii = '';

        for ($i = 0; $i < strlen($chunk); $i++) {
            $byte = ord($chunk[$i]);
            $hex .= sprintf("%02X ", $byte);
            // 可打印字符显示原字符,否则显示点号
            $ascii .= ($byte >= 32 && $byte <= 126) ? $chunk[$i] : '.';
        }

        // 补齐不足16字节时的空格
        $hex = str_pad($hex, 16 * 3);

        // 输出格式:偏移地址 + 十六进制 + ASCII
        printf("%08X  %s %s\n", $offset, $hex, $ascii);

        $offset += 16;
    }
}

实例:用 hexdump() 查看 pack() 的结果

假设我们要用 pack() 函数打包几个数据,并用 hexdump() 查看:

<?php
// 打包数据:1字节无符号字符,2字节网络序,4字节小端序
$binary = pack('C n V', 0x41, 0x4243, 0x44454647);

hexdump($binary);
?>

执行后,输出如下:

00000000  41 42 43 47 46 45 44 00 00 00 00 00 00 00 00 00  ABCGFED..........

解析

  • 0x41 是字符 'A'

  • 0x4243 按网络字节序存储为 42 43 ('B' 'C')

  • 0x44454647 按小端序存储为 47 46 45 44 (对应ASCII 'G' 'F' 'E' 'D')


注意事项

  • pack() 函数的格式字符串非常强大,详细格式请查阅官方文档,如 m66.net/manual/en/function.pack.php

  • hexdump() 的实现可以根据需求调整,比如支持更多格式、显示更多注释等。

  • 二进制数据中非可打印字符无法直观看懂,借助 hexdump() 可以方便调试。


通过以上方法,开发者能够直观地观察 pack() 打包后的二进制结构,有助于调试和理解数据格式。希望本文能帮你快速上手 hexdump()pack() 的配合使用。