對於網絡通信及文件存儲過程中,數據需以二進制形式進行傳輸及存儲。PHP提供了pack()函數用於將不同類型的數據打包成一個二進制字符串,反之unpack()函數用於解包一個二進制字符串為原始數據,下面將從多個方面詳細闡述pack()函數的應用及使用方法。
一、pack()函數概述
pack()函數的基本語法如下:
string pack(string $format, mixed $args1 [, mixed $args2...]);
其中,$format是格式字符串,用於指定要打包的數據類型及數據順序;$args是要打包的數據參數。pack()函數會將所指定的參數按照格式字符串中指定的順序打包成二進制字符串並返回。
下面將介紹常用的數據類型及其格式說明符:
- 整型:i表示有符號整型,I表示無符號整型,n表示無符號短整型,N表示無符號長整型
- 浮點型:f表示單精度浮點型,d表示雙精度浮點型
- 布爾型:c表示char型,將任何非零值打包為字符1,而0打包為空字符
- 字符串:a表示字符串。
下面給出一個實際的例子,將整型數值2和浮點型數值3.14打包成一個二進制字符串:
$binary_data = pack("If", 2, 3.14);
執行後,$binary_data的值為二進制字符串”\x02\x9c\x28\x5c\x8f\xc2\xf5\x3f”。
二、pack()函數格式字符串的使用方法
在使用pack()函數時,格式字符串的正確使用十分重要,下面介紹pack()函數格式字符串的使用方法。
1、指定數據類型及數據順序:格式字符串首先需要指定要打包的數據類型及數據順序,如’i’表示有符號整型,’I’表示無符號整型,’n’表示無符號短整型,’N’表示無符號長整型等,而’!’表示不受主機字節序的影響,使用網絡字節序。
2、指定數據長度:格式字符串可以通過數字及’*’來重複指定數據類型,如’2i’表示兩個有符號整型,’3*’表示三個字符串,’*’表示剩餘部分打包為字符串。
3、指定數據的字節序:格式字符串也可以使用’H’、’h’、’s’、’S’、’l’及’L’來指定不同的字節序。如’H’表示按照高位優先的十六進制數據格式打包成字符串(也稱big-endian字節序),’h’表示按照低位優先的十六進制數據格式打包成字符串(也稱little-endian字節序),’s’表示按照本機字節序的短整型數據格式打包成字符串,’S’表示按照網絡字節序的無符號短整型數據格式打包成字符串,’l’表示按照本機字節序的長整型數據格式打包成字符串,’L’表示按照網絡字節序的無符號長整型數據格式打包成字符串。
下面給出一個實際的例子,將整型數值2、長整型數值4000000000、無符號短整型數值65535及字符串“hello” 打包成一個二進制字符串:
$binary_data = pack("InS5a", 2, 4000000000, 65535, 'hello');
三、unpack()函數概述
unpack()函數是pack()函數的反向操作,用於將一個二進制數據字符串解包成原始數據。unpack()函數的基本語法如下:
mixed unpack(string $format, string $binary_string);
其中,$format是格式字符串,用於指定解包的數據類型及數據順序;$binary_string是要解包的二進制字符串。
unpack()函數返回解包後的數據,數據類型及數據順序與pack()函數的$format字符串對應。如果要解包的數據包含多個類型的數據,則返回一個關聯數組。
四、應用舉例
1、打包IPv4地址信息
下面代碼演示如何將IPv4地址信息打包成一個二進制字符串:
$ip = "192.168.1.100"; $binary_ip = pack("CCCC",...explode('.', $ip));
執行後,$binary_ip的值為二進制字符串”\xC0\xA8\x01\x64″(十進制為192.168.1.100)。
2、發送結構化數據
下面代碼演示如何將結構化數據(例:用戶名和密碼)以二進制數據形式發送到服務器端:
$username = "user"; $password = "123456"; $binary_data = pack("a20a20", $username, $password); socket_write($socket, $binary_data);
其中,’a20’表示長度為20的字符串。
3、解包結構化數據
下面代碼演示如何將服務器端返回的二進制數據解包成結構化數據(例:用戶名和密碼):
$packet = socket_read($socket, 1024); $result = unpack("a20username/a20password", $packet); echo "Login Success: " . trim($result['username']) . " " . trim($result['password']);
其中,’a20username’表示長度為20的字符串類型數據命名為username,’a20password’表示長度為20的字符串類型數據命名為password。
總結
本文詳細闡述了利用pack()函數進行二進制數據打包和解包的方法及應用,掌握了本文所述內容後,可以更好地處理二進制數據相關的工作,提高程序的效率及可讀性。
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/252095.html