當前位置: 首頁> 最新文章列表> 如何用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()的配合使用。