當前位置: 首頁> 最新文章列表> pack() 與ord() 的互補使用

pack() 與ord() 的互補使用

M66 2025-06-06

1. pack()的基本用法

pack()函數將指定的格式字符串和數據打包成二進製字符串。例如, pack("C", 65)會返回一個包含ASCII 碼為65(即字符"A")的單個字符的二進製字符串。格式字符串用於描述數據的佈局,常用的格式代碼包括:

  • C :無符號字符(8位,範圍0–255)

  • n :無符號短整型(16位,大端字節序)

  • N :無符號長整型(32位,大端字節序)

  • H* :十六進製字符串(高位優先)

舉個例子:

 $bin = pack("C*", 72, 101, 108, 108, 111); // 對應字符 "Hello"
echo $bin; // 輸出 Hello

這個過程就像是將一個整數數組轉換為一個壓縮後的二進製字符串。


2. ord()的基本用法

pack()相反, ord()用於將字符轉換成其對應的ASCII 或Unicode 值。它是pack()的“解碼器”,在從二進製字符串中提取數據時非常有用。

例如:

 $char = "A";
$ascii = ord($char); // 返回 65

這個函數非常適合與pack()配合,從編碼後的字符串中逐字節恢復原始數據。


3. 兩者的互補關係

將數據編碼為二進制時用pack() ,將其從二進制中提取出來時用ord() 。這構成了兩者互補的關係。比如,我們可以先將一個數字序列打包,然後再逐字節解析出來:

 $data = [77, 54, 54];
$bin = pack("C*", ...$data);

// 讀取每個字節
for ($i = 0; $i < strlen($bin); $i++) {
    echo ord($bin[$i]) . "\n"; // 輸出 77, 54, 54
}

這段代碼中,我們用pack()將數組[77, 54, 54]轉為一個三字節的二進製字符串,而ord()則逐字節還原為原始數值。

這種技巧在構造特定協議的二進制報文時尤其有用。例如構造一個類似短鏈接請求包:

 $url_id = 1234;
$payload = pack("N", $url_id);
file_put_contents("http://m66.net/api/store", $payload);

服務器接收到這個4 字節數據後,可用如下方式解析:

 $data = file_get_contents("php://input");
$url_id = unpack("N", $data)[1];

這裡pack("N", $url_id)unpack("N", $data)正好是一對互補操作。


4. 實戰場景舉例

例如,在實現某種輕量級加密或自定義傳輸協議時,你可能需要把文本信息按字節轉換為數值、做一定的偏移處理後再封裝為二進制:

 $text = "Hi!";
$encrypted = "";
for ($i = 0; $i < strlen($text); $i++) {
    $encrypted .= pack("C", ord($text[$i]) + 1);
}
// 解密
$decrypted = "";
for ($i = 0; $i < strlen($encrypted); $i++) {
    $decrypted .= chr(ord($encrypted[$i]) - 1);
}
echo $decrypted; // 輸出 Hi!

這個例子中ord()將字符變為數字, pack()封裝為二進制,解密過程則用ord()還原後再偏移。