pack 和 unpack 的使用

2021-06-16 04:32:01 字數 2796 閱讀 2595

來自kakapo的部落格:

任何一款擁有socket操作能力的語言都有乙個專門用於組包的函式,php也不例外!

用了很久php了卻很少有機會用php進行一些二進位制操作。 最近用php寫乙個socket客戶端連線乙個用c++語言開發的遊戲服務端。 伺服器端開發人員使用了二進位制的形式來定義協議的格式。協議格式如下:

包頭(2bytes)+加密(1byte)+命令碼(2bytes)+幀內容

1.包頭的內容是記錄幀內容的長度;

2. 加密:0表示不加密,1表示加密;

3. 命令碼為服務端命令識別符號;

一開始不了解php原來有pack可以來組裝二進位製包, 走了彎路,讓服務端開發人員用c語言幫忙開發了的幾個記憶體操作函式,按照協議規則返回二進位製包,然後我將這幾個方法編譯成一組擴充套件函式供php使用。

話歸正題,本文是介紹如何使用pack和unpack這兩個方法的。php官方手冊舉例太少,不能很容易理解,特別是那些格式化引數的使用。

轉 摘的引數中文說明:

pack/unpack 的摸板字元字元 含義

a 乙個填充空的位元組串

a 乙個填充空格的位元組串

b 乙個位串,在每個位元組里位的順序都是公升序

b 乙個位串,在每個位元組里位的順序都是降序

c 乙個有符號 char(8位整數)值

c 乙個無符號 char(8位整數)值;關於 unicode 參閱 u

d 本機格式的雙精度浮點數

f 本機格式的單精度浮點數

h 乙個十六進製制串,低四位在前

h 乙個十六進製制串,高四位在前

i 乙個有符號整數值,本機格式

i 乙個無符號整數值,本機格式

l 乙個有符號長整形,總是 32 位

l 乙個無符號長整形,總是 32 位

n 乙個 16位短整形,「網路」位元組序(大頭在前)

n 乙個 32 位短整形,「網路」位元組序(大頭在前)

p 乙個指向空結尾的字串的指標

p 乙個指向定長字串的指標

q 乙個有符號四倍(64位整數)值

q 乙個無符號四倍(64位整數)值

s 乙個有符號短整數值,總是 16 位

s 乙個無符號短整數值,總是 16 位,位元組序跟機器晶元有關

u 乙個無編碼的字串

u 乙個 unicode 字元數字

v 乙個「vax」位元組序(小頭在前)的 16 位短整數

v 乙個「vax」位元組序(小頭在前)的 32 位短整數

w 乙個 ber 壓縮的整數

x 乙個空位元組(向前忽略乙個位元組)

x 備份乙個位元組

z 乙個空結束的(和空填充的)位元組串

@ 用空位元組填充絕對位置

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

一些規則:

1. 每個字母後面都可以跟著乙個數字,表示 count(計數),如果 count 是乙個 * 表示剩下的所有東西。

2.如果你提供的引數比 $format 要求的少,pack 假設缺的都是空值。如果你提供的引數比 $format 要求的多,那麼多餘的引數被忽略。

下面還 是用例子來說明用法會容易理解一點:

關於pack:

下 面的第一部分把數字值包裝成位元組:

$out = pack("cccc", 65, 66, 67, 68);      # $out 等於"abcd"

$out = pack("c4", 65, 66, 67, 68);         # 一樣的東西

下面 的對 unicode 的迴圈字母做同樣的事情:

$foo = pack("u4", 0x24b6, 0x24b7, 0x24b8, 0x24b9);

下面的做類似的事情,增加了一些空:

$out = pack("ccxxcc", 65, 66, 67, 68);      # $out 等於 "ab/0/0cd"

打包你的短整數並不意味著你就可移植了:

$out = pack("s2", 1, 2);        

# 在小頭在前的機器上是 "/1/0/2/0"

# 在大頭在前的機器上是 "/0/1/0/2"

在二進位制和十六進製制包裝上,count 指的是位或者半位元組的數量,而不是生成的位元組數量:

$out = pack("b32", "...");

$out = pack("h8", "5065726c");         # 都生成「perl」

a 域裡的長度只應用於乙個字串:

$out = pack("a4", "abcd", "x", "y", "z");      # "abcd"

要繞開這個限制,使用多倍宣告:

$out = pack("aaaa",    "abcd", "x", "y", "z");   # "axyz"

$out = pack("a" x 4,   "abcd", "x", "y", "z");   # "axyz"

a 格式做空填充:

$out = pack("a14", "abcdefg");         # " abcdefg/0/0/0/0/0/0"

關於unpack:

array unpack ( string $format, string $data )

$data = "010000020007";

unpack("sint1/cchar1/sint2/cchar2",$data);

## array('int1'=>1, 'char1'=>'0','int2'=>2,'char2'=>7);

最後本文開頭講到的協議使用pack/unpack 舉例程式**為 :

socket中pack 和 unpack 的使用

任何一款擁有socket操作能力的語言都有乙個專門用於組包的函式,php也不例外 用了很久php了卻很少有機會用php進行一些二進位制操作。最近用php寫乙個socket客戶端連線乙個用c 語言開發的遊戲服務端。伺服器端開發人員使用了二進位制的形式來定義協議的格式。協議格式如下 包頭 2bytes ...

Python pip批量安裝和解除安裝package

requirements.txt requirements.txt 檔案 裡面記錄了當前程式的所有依賴包及其精確版本號。將需要安裝的包儲存在aa.txt中 aa.txt 指定版本 aa.txt 不指定版本 cd到aa.txt所在目錄,執行 pip install r aa.txt將需要解除安裝的包儲...

RNN 網路中文字的 pack 和 pad 操作

rnn 模型一般設定固定的文字長度 text sequence length,可理解為文字序列在時間維度上的步數 time step 以保證網路輸出 層資料維度的一致性。但在訓練和測試時,難以保證輸入文字長度的一致性,因此常常需要截斷操作 即將超過預設長度的文字截斷 和 pad 操作 即對不足預設長...