php - pack() 打包函數(shù)的理解

pack — 將數(shù)據(jù)打包成二進(jìn)制字符串

總是無(wú)法把這個(gè)函數(shù)的用法跟它的函數(shù)說(shuō)明聯(lián)系起來(lái),我都有點(diǎn)懷疑是不是描述錯(cuò)了。
首先要了解二進(jìn)制字符串,才能比較好理解這個(gè)函數(shù):

二進(jìn)制字符串

字面上理解『二進(jìn)制字符串』應(yīng)該是像 01010101這樣的東西,我以前一直也是這樣理解的,直到遇到了 pack()函數(shù),讓我有點(diǎn)懷疑人生。
我們其實(shí)是沒(méi)辦法直接看到二進(jìn)制碼的,我們?cè)谄聊簧峡吹降乃?,其?shí)都是二進(jìn)制碼的表現(xiàn)形式,也就是這里說(shuō)的二進(jìn)制字符串。什么意思呢?

/**
 * 我們看到的 a 是一個(gè)字符串,它就是一個(gè)二進(jìn)制字符串
 * a 是二進(jìn)制碼 01100001 的表現(xiàn)形式
 */
$str = 'a';

/**
 * n 無(wú)符號(hào)短整型(16位,大端字節(jié)序)
 * 把 97 當(dāng)成 16位無(wú)符號(hào)短整型 存入2個(gè)字節(jié)大小的二進(jìn)制碼里,表現(xiàn)為 a
 */
$bin_str = pack('n', 97);
echo '|', $bin_str, "\n";     // 輸出: | a
echo strlen($bin_str);        // 輸出 2, 變量$bin_str 占兩個(gè)字節(jié)

模擬 pack() 函數(shù)進(jìn)行數(shù)據(jù)打包

$int = 97;
$int = 299;
$int = 65579;
$r1 = packShortIntTo2bytes($int);
$r2 = pack('n', $int);

printf("r1 = |%s\n", $r1);
printf("r2 = |%s\n", $r2);
printf("r2 len: %d\n", strlen($r1));
printf("r2 len: %d\n", strlen($r2));


/**
 * 將16位短整型打包成2字節(jié)的二進(jìn)制字符串
 *
 * 這里直接利用php函數(shù)的便利寫的, 還是可以有其他的實(shí)現(xiàn)方式
 * 最直接的實(shí)現(xiàn)方式步驟:
 *  1.先將整數(shù)轉(zhuǎn)成二進(jìn)制字符的表現(xiàn)形式: 001010101
 *  2.再將二進(jìn)制字符補(bǔ)足8的倍數(shù), 如果從低位解析就不用
 *  3.取出每8位一個(gè)字節(jié)的二進(jìn)制字符, 將其轉(zhuǎn)為整型: bindec()
 *  4.用 chr() 函數(shù)將整數(shù)轉(zhuǎn)成 ascii 所對(duì)應(yīng)的字符
 *  5.將字符拼接起來(lái)
 * 還沒(méi)有試過(guò), 理論上也是可行的
 * 
 * @param int $int
 * @return bool|string
 */
function packShortIntTo2bytes(int $int) {
    if ($int > 65536) {
        $int = $int % 65536;
    }
    # 先轉(zhuǎn)成 16 進(jìn)制
    $hex = dechex($int);
    # 確保是 4 位的16進(jìn)制, 16位的二進(jìn)制可以用4位十六進(jìn)制表示
    if (strlen($hex) < 4) {
        $hex = str_pad($hex, 4, '0', STR_PAD_LEFT);
    }
    # 最后將十六進(jìn)制字符串轉(zhuǎn)成二進(jìn)制字符串
    return hex2bin($hex);
}

將數(shù)據(jù)打包成二進(jìn)制字符串的作用

打包數(shù)據(jù),就是壓縮數(shù)據(jù)。
我們將一個(gè)整型 9999 存入一個(gè)文件里面,就是一個(gè)占用 4 字節(jié)的字符串。
但如果把 9999 打包成16位的無(wú)符號(hào)短整型,就只是占用2個(gè)字節(jié),16位的無(wú)符號(hào)短整型可以表示 0 ~ 65536 的整數(shù)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容