pack和unpack:二进制字符流的处理利器

文件除了是二进制流外,其保存的结构和数据类型以及文件定义的保存结构有关。

1、big-endian和little-endian之分,如地址0x3BEF,按big-endian,保存为 3B EF;按little-endian,保存为EF 3B。

2、与数据类型有关。如数值01,按单字节保存为01,按short保存,为00 01;按Long类型保存,为00 00 00 01。

pack——将数值保存成符合文件要求的格式的二进制文件流

pack('k1k2k3k4...',$arg1,$arg2,$arg3,$arg4...)——将$arg1,$arg2,$arg3,$arg4...等数值按K1,K2,K3,K4....的格式转换成二进制流。

K1,K2,K3,K4文件取值如下表

 
CodeDescription
aNUL-padded string
ASPACE-padded string
hHex string, low nibble first,低位优先16进制字符
HHex string, high nibble first,高位优先16进制字符
csigned char,带符号单字节
Cunsigned char,无符号单字节
ssigned short (always 16 bit, machine byte order),有符号双字节,顺序按机器设定
Sunsigned short (always 16 bit, machine byte order)无符号双字节,顺序按机器设定
nunsigned short (always 16 bit, big endian byte order)无符号双字节,高位优先
vunsigned short (always 16 bit, little endian byte order)无符号双字节,低位优先
isigned integer (machine dependent size and byte order)有符号整数,字节数和顺序按机器设定
Iunsigned integer (machine dependent size and byte order)无符号整数,字节数和顺序按机器设定
lsigned long (always 32 bit, machine byte order)有符号4字节数,顺序按机器设定
Lunsigned long (always 32 bit, machine byte order)无符号4字节数,顺序按机器设定
Nunsigned long (always 32 bit, big endian byte order)无符号4字节数,高位优先
Vunsigned long (always 32 bit, little endian byte order)无符号4字节数,低位优先
qsigned long long (always 64 bit, machine byte order)有符号8字节数,顺序按机器设定
Qunsigned long long (always 64 bit, machine byte order)无符号8字节数,顺序按机器设定
Junsigned long long (always 64 bit, big endian byte order)无符号8字节数,高位优先
Punsigned long long (always 64 bit, little endian byte order)无符号8字节数,低位优先
ffloat (machine dependent size and representation)浮点数,字节数和顺序按机器设定
gfloat (machine dependent size, little endian byte order)浮点数,字节数按机器设定,高位优先
Gfloat (machine dependent size, big endian byte order)浮点数,字节数按机器设定,低位优先
ddouble (machine dependent size and representation)双精度数,字节数和顺序按机器设定
edouble (machine dependent size, little endian byte order)双精度数,字节数按机器设定,高位优先
Edouble (machine dependent size, big endian byte order)双精度数,字节数按机器设定,低位优先
xNUL byte
XBack up one byte
ZNUL-padded string (new in PHP 5.5)
@NUL-fill to absolute position

示例:

pack('nnnn',79,79,78,78)=>00  79 00 79 00 78 00 78(为简单,用十进制表示);

pack('cnnN',79,79,78,78)=> 79 00 79 00 78 00 00 00 78;

pack('cnvV',79,79,78,78)=> 79 00 79 78 00 78 00 00 00;

unpack——将二进制文件流按文件结构转换成数值,pack的逆过程

(一)unpack解析

1、用法:

unpack(format,$binary),返回带key的数组。

2、参数format

format由多个数值描述组成,每个描述用'/'表示区分,每个描述由3个参数组成:[type][ number][ key],故format可写成:

[type1][ number1][ key1]/[type2][ number2][ key2]/[type3][ number3][ key3]/....

[type]就是上面的code,代表数据的类型;

[number]表示该类型数据由多少个,可以缺省不写,代表一个;

[key]返回的数组中该数值的key。可以不写没有指定key,自动用1,2,3,取代;如果相同格式的数值使用同一个key,会自动递增key1,key2,key3.....

(二)列举format的写法

1、相同格式的数据流format不同写法

unpack('n*','00  79 00 79 00 78 00 78')=>['1'=>79,'2'=>79,'3'=>78,'4'=>78]//*代表不断循环,直至数据流结束;key按数字1,2,3递增;

unpack('n4','00  79 00 79 00 78 00 78')=>['1'=>79,'2'=>79,'3'=>78,'4'=>78]//提取4个2字节;key按数字1,2,3递增;

unpack('n4data','00  79 00 79 00 78 00 78')=>['data1'=>79,'data2'=>79,'data3'=>78,'data4'=>78]//提取4个2字节;key以data为前缀,按数字1,2,3递增;

unpack('n2data/n2num','00  79 00 79 00 78 00 78')=>['data1'=>79,'data2'=>79,'num3'=>78,'num4'=>78]//前两个2字节;key以data为前缀,按数字1,2,3递增;后2个提取2个字节,以num为前缀,递增;

unpack('n2data/n2data','00  79 00 79 00 78 00 78')=>['data1'=>78,'data2'=>78]//由于后面的前缀和前面两个前缀一致,导致数组中同key被覆盖,所以只返回最后两个数值。

unpack('n2/n2','00  79 00 79 00 78 00 78')=>['1'=>78,'2'=>78]//原因同上。

unpack('nwidth/nheight/ndepth/nfilter','00  79 00 79 00 78 00 78')=>['width'=>79,'height'=>79,'depth'=>78,'filter'=>78]//给每个数值设置不同的key。

2、不同格式的数据流format写法

unpack('n1data/c6num','00  79 00 79 00 78 00 78')=>['data1'=>79,'num1'=>00,'num2'=>79,'num3'=>00,'num4'=>78,'num5'=>00,'num6'=>78];

unpack('ndata/c/cnum/cwidth/cheight/c2tt','00  79 00 79 00 78 00 78')=>['data'=>79,'1'=>00,'num'=>79,'width'=>00,'height'=>78,'tt1'=>00,'tt2'=>78];

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值