嘗試使用 pack 與 unpack 函式

icecho發表於2019-03-15

今天接觸了兩個比較冷門的函式 packunpack,查閱了相關資料,想和大家分享一下,這兩個函式是處理 位元組 的函式,首先再梳理了一下它們的關係。

日常工作學習中,與 字串 接觸比較多,但字元的伴生概念:位元組,我不太熟悉。

它們之間有什麼區別呢?

簡單來說 位元組 是計算機儲存和操作的最小單位,字元 是人們閱讀的最小單位;位元組 是儲存(物理)概念,字元 是邏輯概念;位元組 代表資料(內涵和本質),字元 代表其含義;字元位元組 組成。好像有點繞。

比如說:我們們的首都,”北京” 包含 2 個字元,在 UTF-8 編碼格式下它需要 6 個位元組,數字 “666666”,包含 6 個字元,用 int 型別表示只需要 4 個位元組。

位元組處理函式

PHP 內建的字串函式有非常多,但是位元組處理函式比較少,今天接觸了 packunpack,想和大家一起再學習學習。

作用

將資料打包成二進位制字串

使用

pack ( string $format [, mixed $args [, mixed $... ]] ) : string

引數

  • format 這個引數由格式程式碼組成,緊跟著一個可選的重複引數(可以是一個整數值或用 * 來表示重複到輸入資料的末尾),對於 aAhH 來說此引數指定了給定資料會被使用幾個字串,對於 @ 來說其後的數字表示放置剩餘資料的絕對定位(之前的會被空字串填充),對於其他內容,重複數量指定消耗多少資料進行 pack 操作。
  • args

返回值

返回包含資料的二進位制字串。

例子

var_dump(pack('C', 80))
var_dump(pack('C*', 80, 72, 80)) 

"P"
"PHP"

作用

從二進位制字串中解壓縮資料

使用

unpack ( string $format , string $data [, int $offset = 0 ] ) : array

引數

  • format 參閱上面的 pack
  • data 想要釋放的資料
  • offset 從何處開始釋放

返回值

返回包含二進位制字串的解壓縮元素的關聯陣列。

例子

var_dump(unpack('C', 'P'))
var_dump(unpack('C*', 'PHP')) 

[ 
    1 => 80,
]

[ 
    1 => 80, 
    2 => 72, 
    3 => 80,
]

有一點需要注意。

unpack('H*hello/C*world', 'PHP')

[
     "hello" => "504850",
     "world1" => 80,
     "world2" => 72,
     "world3" => 80,
]

unpack('H*/C*', 'PHP')

[
     1 => 80,
     2 => 72,
     3 => 80,
]

為啥會這樣呢?文件是這麼說的

Caution
If you do not name an element, numeric indices starting from 1 are used. Be aware that if you have more than one unnamed element, some data is overwritten because the numbering restarts from 1 for each element.

意思是說,如果我們不對資料命名,預設使用從 1 開始的數字索引,所以如果不命名,後面的會覆蓋前面的資料。

雖然這兩個函式用的極少,但是還是在某些場景能用上。

在琢磨 redis 位運算統計的時候,琢磨把二進位制字串解壓縮資料,就用上了嘛!

$pack = unpack('C*', '\x00\x10')

$tmp = array_map(function ($val) {
        $val = base_convert($val, 10, 2);
        $val = str_pad($val, 8, 0, STR_PAD_LEFT);
        return $val;
    }, $pack);

echo implode(' ', $tmp);

01011100 01111000 00110000 00110000 01011100 01111000 00110001 00110000

ASCII
pack函式
unpack函式
base_convert函式
PHP中的pack和unpack函式
如何利用 Redis 快速實現簽到統計功能
Redis 中 BitMap 是如何儲存的,以及 PHP 如何處理

這是我潛伏這麼久以來,第一次嘗試書寫文章,可能不通順,大家見諒哈。

還要感謝 OvertrueLhao 兩位帥哥!

本作品採用《CC 協議》,轉載必須註明作者和本文連結

Hello。

相關文章