前面在研究websocket的时候用到了pack跟unpack方法,这两个方法一直让我感觉起来比较深奥,当时从网上找了很多资料来研究,现在把这两个函数的使用方法以及参数介绍记下来,以作备忘
先看pack方法的说明:
pack -- 将数据打包成二进制字符串
语法:string pack(string format, mixed [args]...);
参数一:format参数表示以什么格式格式化数据
参数二:将被格式化的数据
参数一的可选值:
a | NUL-padded string NULL填充字符串空白格式,返回1位,默认读取10进制数据 |
A | SPACE-padded string SPACE填充字符串空白格式,返回1位,默认读取10进制数据 |
h | Hex string, low nibble first 十六进制格式,每次格4位,低四位在前,默认读取10进制数据 |
H | Hex string, high nibble first 十六进制格式,每次格4位,高四位在前,默认读取10进制数据 |
c | signed char 有符号字符格式,每次格8位,默认读取16进制数据 |
C | unsigned char 无符号字符格式,每次格8位,默认读取16进制数据 |
s | signed short (always 16 bit, machine byte order) 有符号短整型格式(每次格16位,以计算机字节顺序),默认读取16进制数据 |
S | unsigned short (always 16 bit, machine byte order) 无符号短整型格式(每次格16位,以计算机字节顺序),默认读取16进制数据 |
n | unsigned short (always 16 bit, big endian byte order) 无符号短整型(每次格16位,以低端地址存放高位数据顺序),默认读取16进制数据 |
v | unsigned short (always 16 bit, little endian byte order) 无符号短整型(每次格16位,以低端地址存放低位数据顺序),默认读取16进制数据 |
i | signed integer (machine dependent size and byte order) 有符号整形(每次格机器最大寻址位数的数据,以计算机字节顺序),默认读取16进制数据 |
I | unsigned integer (machine dependent size and byte order) 无符号整形(每次格机器最大寻址位数的数据,以计算机字节顺序),默认读取16进制数据 |
l | signed long (always 32 bit, machine byte order) 有符号长整型格式(每次格32位,以计算机字节顺序),默认读取16进制数据 |
L | unsigned long (always 32 bit, machine byte order) 无符号长整型格式(每次格32位,以计算机字节顺序),默认读取16进制数据 |
N | unsigned long (always 32 bit, big endian byte order) 无符号长整型格式(每次格32位,以低端地址存放高位数据顺序),默认读取16进制数据 |
V | unsigned long (always 32 bit, little endian byte order) 无符号长整型格式(每次格32位,以低端地址存放低位数据顺序),默认读取16进制数据 |
f | float (machine dependent size and representation) 单精度实型格式(取决于机器的最大寻址位数和表示) |
d | double (machine dependent size and representation) 双精度实型格式(取决于机器的最大寻址位数和表示) |
x | NUL byte |
X | Back up one byte |
@ | NUL-fill to absolute position |
下面以具体的例子来讲解一下每个参数的用法:
echo pack("a", 0x41); //输出6
将一个十六进制数据0x41以十进制的方式读取,0x41转换成十进制是65,取一位返回就是6
echo pack("a2", 0x41); //输出65
此代码为取两位返回为65
echo pack("H2", 0x41); //输出e
将一个十六进制数据0x41以十进制的方式读取,由于H是每次格4位,这里用了H2,代表格8位,由于高位在前,0x41转换成十进制是65,65被H2格式化之后是0X65,转换成ASC码是e
echo pack("c", 0x41); //输出A
0x41是十六进制的数据,所以经过c格式化之后是0x41,转换成ASC码是A
echo pack("c", 65); //输出A
将十进制数据65以十六进制的方式读取,65转换成十六进制是0x41,然后经过c格式化,转换成ASC码是A
echo pack("s", 0x4143424445); //输出ED
十六进制数据0x4143424445,经过s格式化,由于是按计算机字节的循序,所以从低位数据开始,格式化16位,返回0x45,0x44,转换成ASC码是ED
关于低位地址存放高位数据
数据:0x4143424445
位置:高位 <-- 低位
因为低端地址存放高端数据,41是最高端有效数据,所以存放在最低端地址,顺序为:
数据:41 43 42 44 45
位置:低端地址->高端地址
echo pack("n", 0x4143424445); //输出DE
将0x4143424445以十六进制方式读取,然后经过n格式化,由于是按照以低端地址存放高位数据顺序方式,格16位数据,返回0x44,0x45, 转换成ASC码是DE
echo pack("v", 0x4143424445); //输出ED
将0x4143424445以十六进制方式读取,然后经过v格式化,由于是按照以低端地址存放低位数据顺序方式,格16位数据,返回0x45,0x44, 转换成ASC码是ED
echo pack("i", 0x4143424445); //输出EDBC
将0x4143424445以十六进制方式读取,然后经过i格式化,由于xp系统的最大寻址位数是32位,所以格32位数据并以计算机字节顺序,返回0x45,0x44,0x42,0x43,转换成ASC码是EDBC
echo pack("l", 0x4143424445); //输出EDBC
过程同s,这里是格式化32位数据字节,所以返回EDBC
echo pack("N", 0x4143424445); //输出CBDE
过程同n,这里同样格式化32位数据字节,返回CBDE
对于pack,如果提供的数据不是format默认读取的数据进制,则会先转换为相应的数据进制,再进行打包操作