您现在的位置是:首页>>文章详情文章详情

PHPpack()函数用途及详解

[PHP]2018-07-05 21:12:15

PHP中有两个函数pack和unpack,很多PHPer在实际项目中从来没有使用过,甚至也不知道这两个方法是用来干嘛的。今天用通讯协议生成写入命令时,遇到需要转换进制的问题,特此记录一下。

        进入正题。

定义和用法

pack() 函数把数据装入一个二进制字符串。


第一个参数必填,规定在包装数据时所使用的格式。。具体参数参照下表:

a - NUL-padded string

A - SPACE-padded string

h - Hex string, low nibble first

H - Hex string, high nibble first

c - signed char

C - unsigned char

s - signed short (always 16 bit, machine byte order)

S - unsigned short (always 16 bit, machine byte order)

n - unsigned short (always 16 bit, big endian byte order)

v - unsigned short (always 16 bit, little endian byte order)

i - signed integer (machine dependent size and byte order)

I - unsigned integer (machine dependent size and byte order)

l - signed long (always 32 bit, machine byte order)

L - unsigned long (always 32 bit, machine byte order)

N - unsigned long (always 32 bit, big endian byte order)

V - unsigned long (always 32 bit, little endian byte order)

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

CodeDescription
a以NUL字节填充字符串空白
A以SPACE(空格)填充字符串
h十六进制字符串,低位在前
H十六进制字符串,高位在前
c有符号字符
C无符号字符
s有符号短整型(16位,主机字节序)
S无符号短整型(16位,主机字节序)
n无符号短整型(16位,大端字节序)
v无符号短整型(16位,小端字节序)
i有符号整型(机器相关大小字节序)
I无符号整型(机器相关大小字节序)
l有符号长整型(32位,主机字节序)
L无符号长整型(32位,主机字节序)
N无符号长整型(32位,大端字节序)
V无符号长整型(32位,小端字节序)
q有符号长长整型(64位,主机字节序)
Q无符号长长整型(64位,主机字节序)
J无符号长长整型(64位,大端字节序)
P无符号长长整型(64位,小端字节序)
f单精度浮点型(机器相关大小)
d双精度浮点型(机器相关大小)
xNUL字节
X回退一字节
Z以NUL字节填充字符串空白(new in PHP 5.5)
@NUL填充到绝对位置

ps:在使用的时候发现,‘s’‘S’‘n’中并没有出现大端有符号短整型的格式,临时处理方法,做了一个两位的反转将小端转换为大端的写法。如有其他解决办法,请不吝指教...


这么多参数,还是比较好理解的,但是其中的主机、大端、小端等字节序是什么?


计算机硬件有两种储存数据的方式:大端字节序(big endian)和小端字节序(little endian)。

举例来说,数值0x2211使用两个字节储存:高位字节是0x22,低位字节是0x11。

  • 大端字节序:高位字节在前,低位字节在后,这是人类读写数值的方法。


  • 小端字节序:低位字节在前,高位字节在后,即以0x1122形式储存。

首先,为什么会有小端字节序?

答案是,计算机电路先处理低位字节,效率比较高,因为计算都是从低位开始的。所以,计算机的内部处理都是小端字节序。

但是,人类还是习惯读写大端字节序。所以,除了计算机的内部处理,其他的场合几乎都是大端字节序,比如网络传输和文件储存。

计算机处理字节序的时候,不知道什么是高位字节,什么是低位字节。它只知道按顺序读取字节,先读第一个字节,再读第二个字节。

如果是大端字节序,先读到的就是高位字节,后读到的就是低位字节。小端字节序正好相反。

理解这一点,才能理解计算机如何处理字节序。


字节序的处理,就是一句话:

"只有读取的时候,才必须区分字节序,其他情况都不用考虑。"

处理器读取外部数据的时候,必须知道数据的字节序,将其转成正确的值。然后,就正常使用这个值,完全不用再考虑字节序。

即使是向外部设备写入数据,也不用考虑字节序,正常写入一个值即可。外部设备会自己处理字节序的问题。

-摘自 阮一峰的网络日志(原文地址:http://www.ruanyifeng.com/blog/2016/11/byte-order.html )

更详尽解释可去原文查看。


主机字节序一般为小端字节。主机字节序依机器决定的。


unpack()


相关的一个函数,比较好懂,即用此函数,可将pack()格式打包的字符串还原。不做详细解释。


最后!

这两个函数到底有啥用途?

1.数据通信(通过二进制格式与其它语言通信)

2.数据加密(如果不告诉第三方你的打包方式,对方解包的难度就相对很大)

3.节省空间(比如比较大的数字按字符串储存会浪费很多空间,打包成二进制格式才需要4位<32位数字>)

4.欢迎补充。。。


php手册也有英文版的相关解释。



本文参考:

http://www.phpdig.net/ref/rn45re877.html


https://segmentfault.com/a/1190000008305573#articleHeader1   作者: zhjx922

  

2 点赞!

  评论

评论列表:

登录 留言 回顶部