There are two functions pack and unpack in PHP. Many PHPers have never used them in actual projects, and they don’t even know what these two methods are used for. This article mainly talks about how to use pack and unpack in PHP. I hope it can help you.
string pack ( string $format [, mixed $args [, mixed $... ]] )
This function is used to pack the corresponding parameters ($args) into a binary string.
The first parameter, $format, has the following options (there are many optional parameters, and some commonly used ones will be explained later):
a Fill the string blanks with NUL bytes
A With SPACE (space) padding string
h Hexadecimal string, low digit first
H Hexadecimal string, high byte first
c Signed character
C Unsigned character
s Signed short (16 bits, host byte order)
S Unsigned short (16 bits, host byte order)
n Unsigned short (16 bits, big endian) Endianness)
v Unsigned short integer (16 bits, little endian)
i Signed integer (machine dependent big and small endian)
I Unsigned integer (machine dependent) Big and small byte order)
l Signed long integer (32 bits, host byte order)
L Unsigned long integer (32 bits, host byte order)
N Unsigned long integer (32 bits, big endian)
V Unsigned long integer (32 bits, little endian)
q Signed long integer (64 bits, host byte order)
Q Unsigned long integer type (64 bits, host byte order)
J Unsigned long integer type (64 bits, big endian byte order)
P Unsigned long integer type (64 bits , little endian byte order)
f Single precision floating point type (machine dependent size)
d Double precision floating point type (machine dependent size)
x NUL byte
X Fallback one word Section
Z Fill the string blanks with NUL bytes (new in PHP 5.5)
@ Fill NUL to the absolute position
After seeing so many parameters, I was really confused for the first time Wow, most of the instructions are easy to understand, but what is the endianness of the host, big endian, little endian, etc.? The following content is relatively boring, but it must be understood, so stick with it.
就是字节的顺序,说白了就是多字节数据的存放顺序(一个字节显然不需要顺序)。 比如A和B分别对应的二进制表示为0100 0001、0100 0010。对于储存字符串AB,我们可以0100 0001 0100 0010也可以0100 0010 0100 0001,这个顺序就是所谓的字节序。
比如字符串AB,左高右低(我们正常的阅读顺序),A为高字节,B为低字节
假设0x123456是按从高位到底位的顺序储存,内存中是这样存放的: 高地址 -> 低地址12 -> 34 -> 56
大端就是将高位字节放到内存的低地址端,低位字节放到高地址端。网络传输中(比如TCP/IP)低地址端(高位字节)放在流的开始,对于2个字节的字符串(AB),传输顺序为:A(0-7bit)、B(8-15bit)。 那么小端字节序自然和大端相反。
表示当年机器的字节序(也就是网络字节序是确定的,而主机字节序是依机器确定的),一般为小端字节序。
$string = pack('a6', 'china'); var_dump($string); //输出结果: string(6) "china",最后一个字节是不可见的NULecho ord($string[5]); //输出结果: 0(ASCII码中0对应的就是nul)//A同理$string = pack('A6', 'china'); var_dump($string); //输出结果: string(6) "china ",最后一个字节是空格echo ord($string[5]); //输出结果: 32(ASCII码中32对应的就是空格)
Bonus An ASCII table (you can use man ascii to view it under linux/unix)
$string = pack('H3', 281); var_dump($string); //输出结果: string(2) "("for($i=0;$i<strlen($string);$i++) {echo ord($string[$i]) . PHP_EOL; }//输出结果: 40 16
h and H need special explanation, they are corresponding Parameters are treated as hexadecimal characters and then packed. What does that mean? For example, the above 281 will be converted to 0x281 before packaging, because one hexadecimal digit corresponds to four binary digits. The above 0x281 is only 1.5 bytes, and will be supplemented with 0 by default to become 0x2810, the decimal corresponding to 0x28. is 40((), the decimal corresponding to 0x10 is 16 (dle invisible character), do you understand? If you don’t understand, you can leave me a message.
$string = pack('c3', 67, 68, -1); var_dump($string); //输出:string(3) "CD�"for($i=0;$i<strlen($string);$i++) { echo ord($string[$i]) . PHP_EOL; } //输出: 67 68 225
The final output should be 67 68 -1
ord obtains the ASCII code of the character (range 0-255). At this time, the character corresponding to -1 (0000 0001) will be output in the form of complement, which is 255 (1111 1110 + 0000 0001 = 1111 1111)
All integer types are used in exactly the same way. Just pay attention to their bit and byte order. The following uses L as an example to show
$string = pack('L', 123456789); var_dump($string); //输出:string(4) "�["for($i=0;$i<strlen($string);$i++) { echo ord($string[$i]) . PHP_EOL; } //输出: 21 205 91 7
$string = pack('f', 12345.123); var_dump($string);//输出:string(4) "~�@F"var_dump(unpack('f', $string)); //这里提前用到了unpack,后面会讲解 //输出:float(12345.123046875)
f and d are for floating-point number packaging. As for why it is 12345.123 before packaging and 12345.123046875 after unpacking, this has something to do with the storage of floating-point numbers
$string = pack('x'); //打包一个nul字符串echo ord($string); //输出: 0
Regarding
$string = pack('Z2', 'abc5'); //其实就是将从Z后面的数字位置开始,全部设置为nul var_dump($string); //输出:string(2) "a"for($i=0;$i<strlen($string);$i++) { echo ord($string[$i]) . PHP_EOL; } //输出: 97 0
$string = pack('@4'); //我理解为填充N个nulvar_dump($string); //输出: string(4) ""for($i=0;$i<strlen($string);$i++) {echo ord($string[$i]) . PHP_EOL; }//输出: 0 0 0 0
array unpack ( string $format , string $data )
The use of unpack is quite simple. It just talks about unpacking the data packed by pack. What parameters are used when packaging are used to unpack. I am too lazy to explain the specific use. , list a few small examples
$string = pack('L4', 1, 2, 3, 4); var_dump(unpack('L4', $string));//输出:array(4) { [1]=> int(1) [2]=> int(2) [3]=> int(3) [4]=> int(4) }$string = pack('L4', 1, 2, 3, 4); var_dump(unpack('Ll1/Ll2/Ll3/Ll4', $string)); //可以指定key,用/分割//输出:array(4) { ["l1"]=> int(1) ["l2"]=> int(2) ["l3"]=> int(3) ["l4"]=> int(4) }
Data communication (communication with other languages through binary format)
Data encryption (if you don’t tell the third party your packaging method, it will be relatively difficult for the other party to unpack it)
Save space (for example, storing relatively large numbers as strings will waste a lot of space, and only 4 digits
Related recommendations:
Detailed explanation of the use of pack and unpack
The above is the detailed content of How to use pack and unpack in PHP. For more information, please follow other related articles on the PHP Chinese website!