今天接觸了兩個比較冷門的函式 pack
和 unpack
,查閱了相關資料,想和大家分享一下,這兩個函式是處理 位元組
的函式,首先再梳理了一下它們的關係。
日常工作學習中,與 字串
接觸比較多,但字元的伴生概念:位元組
,我不太熟悉。
它們之間有什麼區別呢?
簡單來說 位元組
是計算機儲存和操作的最小單位,字元
是人們閱讀的最小單位;位元組
是儲存(物理)概念,字元
是邏輯概念;位元組
代表資料(內涵和本質),字元
代表其含義;字元
由 位元組
組成。好像有點繞。
比如說:我們們的首都,”北京” 包含 2 個字元,在 UTF-8 編碼格式下它需要 6 個位元組,數字 “666666”,包含 6 個字元,用 int 型別表示只需要 4 個位元組。
位元組處理函式
PHP 內建的字串函式有非常多,但是位元組處理函式比較少,今天接觸了 pack
和 unpack
,想和大家一起再學習學習。
作用
將資料打包成二進位制字串
使用
pack ( string $format [, mixed $args [, mixed $... ]] ) : string
引數
format
這個引數由格式程式碼組成,緊跟著一個可選的重複引數(可以是一個整數值或用 * 來表示重複到輸入資料的末尾),對於a
,A
,h
,H
來說此引數指定了給定資料會被使用幾個字串,對於@
來說其後的數字表示放置剩餘資料的絕對定位(之前的會被空字串填充),對於其他內容,重複數量指定消耗多少資料進行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 如何處理
這是我潛伏這麼久以來,第一次嘗試書寫文章,可能不通順,大家見諒哈。
還要感謝 Overtrue
和 Lhao
兩位帥哥!
本作品採用《CC 協議》,轉載必須註明作者和本文連結