PHP中二进制的编码包pack与解包unpack

1. 为什么使用pack

我们知道,在网络传输过程中,我们的数据都是以二级制的网络报文在进行传输,很多时候,我们多语言之间交互的时候,想在传输的过程中约定传输的头信息,比如常见的http协议 是展示的明文传输的 

GET /game HTTP/1.1
Host: sp0.baidu.com
Connection: keep-alive

但很多时候,比如我们要做的是游戏的排行榜,而游戏的分数来自C++,每次游戏结束我们要刷新排行榜,可能我们之间并没有完整的 session会话来确保我们的通信是可靠的,这时,如果我们互相之间约定一个传输协议,比如请求头中那几位是验证信息,哪几位使我们要传输的数据,如果验证不通过,我们就认为是非法来源,直接返回403等状态码,场景大概是这样。进入pack的主题,怎么用。

2. 使用pack和unpack

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

pack中有多个参数,其中

$format  为格式参数有点类似于c中的print 设置的%s  但是去掉了% 而且更灵活,

               字母数字  或者 字母   或者 字母*

                a12 或者 或者 H*

$args  的个数取决于格式中字母的个数  比如 'a12a13'  就需要两个字符串 分别是12位 和 13 位 位数不足以nul填充

           如果是单个字母不跟数字 则为一位类型的字符

           如果是单个字母跟上 *  则为该类型任意长度的字符 

编码 描述
a 以NUL字节填充字符串空白
A 以SPACE(空格)填充字符串
b 一个位串 每个字节里位的顺序都是升序
B 一个位串 每个字节里位的顺序都是降序
h 十六进制字符串,低4位在前 一位对应二进制的四位
H 十六进制字符串,高4位在前
c 一个有符号字符 char (8位整数)值
C 一个无符号字符 char (8位整数)值 关于Unicode参阅 U
s 有符号短整型(16位,主机字节序)
S 无符号短整型(16位,主机字节序)
n 一个16位无符号短整型(16位,大端字节序) “网络字节序”
v 无符号短整型(16位,小端字节序)
i 有符号整型(机器相关大小字节序)
I 无符号整型(机器相关大小字节序)
l 有符号长整型(32位,主机字节序)
L 无符号长整型(32位,主机字节序)
N 一个16位无符号长整型(32位,大端字节序) “网络字节序”
V 无符号长整型(32位,小端字节序)
q 有符号长长整型(64位,主机字节序)
Q 无符号长长整型(64位,主机字节序)
J 无符号长长整型(64位,大端字节序)
P 无符号长长整型(64位,小端字节序) 一个指向空结尾字符串的指针
p 一个执行定长字符串的指针
u 一个无编码的字串
U 一个Unicode字符数字
f 单精度浮点型(机器相关大小)
d 双精度浮点型(机器相关大小)
x NUL字节
X 回退一字节
Z 以NUL字节填充字符串空白(new in PHP 5.5)
@ NUL填充到绝对位置

同样的解码函数 unpack

array unpack ( string $format , string $data [, int $offset = 0 ] )

第一个也是格式串,单个字母或者多个字母类型的必须使用 (多个字母 \ 不能省略)

              格式名称 格式名称  组成索引数组(好像是从1开始)    或者

              格式名称字段名称 格式名称字段名称  组成键值数组

废话不多说 看两个例子

$username = '[email protected]';
$password = 'b123456';
$packdata   = pack('SCSa32a32',0x0040,0x00,0x0006, $username, $password );
$unpackdata = unpack('Shead/Cflag/Sflag2/a32word/a32passd/',$packdata);

print_r($unpackdata);

$username = '[email protected]';
$packdata   = pack('a32',$username);
$unpackdata = unpack('a*',$packdata);
print_r($unpackdata) ;

猜你喜欢

转载自blog.csdn.net/wujiangwei567/article/details/81134570