PHP的pack/unpack

本文详细介绍了PHP中的pack和unpack函数,它们分别用于将数据打包成二进制字符串和从二进制字符串中解包出数据。文中通过实例演示了如何使用n,v,c,C等格式进行数据转换,并分析了直接打印二进制字符串时的ASCII码对应关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

PHP: pack - Manual PHP中文手册 PHP中国镜像 php 国内镜像 PHP官方网站

PHP: unpack - Manual PHP中文手册 PHP中国镜像 php 国内镜像 PHP官方网站

1、作用

(1)pack:将数据打包成二进制字符串。将输入数据打包成format格式的二进制字符串。 

pack(string $formatmixed ...$values): string

(2)unpack:根据指定的format将二进制字符串解包成数组。

注:对于一个二进制字符串可能是由多部分组成,每部分都是一个<K,V>,多个就是k-v数组了。待会儿看个具体的例子就知道了。

unpack(string $format, string $string, int $offset = 0): array|false

支持的格式如下:

我们简单的关注下几种格式即可。

#n 无符号短整型(16位,大端字节序)  高尾端 尾端放在高地址
#v 无符号短整型(16位,小端字节序)  低尾端 尾端放在低地址
#c 有符号字符
#C 无符号字符
2、使用方式

(1)pack的使用。

#同时将4部分数据按照分别指定的格式打包为二进制字符串,格式如下。
#①将16进制数据0x1234按照n(无符号短整型(16位,大端字节序))格式打包成二进制字符串
#②将16进制数据0x5678按照v(无符号短整型(16位,小端字节序))格式打包成二进制字符串
#③将10进制数据65按照c(有符号字符)格式打包成二进制字符串
#④将10进制数据66按照c(无符号字符)格式打包成二进制字符串

<?php
$binarydata = pack("nvcC", 0x1234, 0x5678, 65, 66);
print_r("packresult:" . $binarydata);  #4xVAB
print_r("<pre>");
?>

输出如下。注:后面会针对这四个元素挨个分析,明确这个“4xVAB”是怎么来的。

(2)unpack的使用。

$elems = unpack("nelem1/velem2/celem3/Celem4", $binarydata);

①知道这个二进制字符串由四部分组成,每部分的格式分别为nvcC;

②上述加了红色背景的就是指定格式,这个要和打包的时候指定的格式保持一致;

③后面紫色的elem1/elem2/elem3/elem4就是你自己取的名字,方便后续对没部分的引用。

④对照输出结果,一目了然。

#对于上面构建的二进制字符串进行unpack。
#已知其由nccC四部分组成就用着四部分就行解析即可。


<?php
$binarydata = pack("nvcC", 0x1234, 0x5678, 65, 66);
print_r("packresult:" . $binarydata);  #4xVAB
print_r("<pre>");

$elems = unpack("nelem1/velem2/celem3/Celem4", $binarydata);
print_r($elems);
print_r("<pre>");
?>


packresult:4xVAB
Array
(
    [elem1] => 4660
    [elem2] => 22136
    [elem3] => 65
    [elem4] => 66
)

输出结果如下:

 显然,4660就是0x1234的十进制结果、22136就是0x5678的十进制结果,65/66同理。

3、具体测试

分析上面这个case,看看直接打印二进制字符串的结果“4xVAB”是怎么来的。

务必对照ascii码表。百度安全验证

#输出了一个4,分析下这个4是怎么来的。
$binarydata = pack("n", 0x1234);
print_r($binarydata);  
print_r("<pre>");


#0x12  Bin(00010010) Dec(18) #查询ascii码表0~31分配给了控制字符;这里的18表示"设备控制2"并不对应可见字符。
#0x34  Bin(00110100) Dec(52) #查询ascii码表对应可打印字符"4"
结论:显然4就是这么来的。




$binarydata = pack("v", 0x5678);
print_r($binarydata);  #xV
print_r("<pre>");


#0x56 Bin(01010110) Dec(56)   #查询ascii码表对应字符V
#0x78 Bin(01111000) Dec(120)  #查询ascii码表对应字符x
结论:又因为v表示小端字节序(低尾端,即尾端在低地址);所以先打印的顺序是xV。



$binarydata = pack("c", 65);
print_r($binarydata);  
print_r("<pre>");

#Dec(65) #查询ascii码表对应可见字符A
#结论:所以输出了A


$binarydata = pack("c", 66);
print_r($binarydata);  
print_r("<pre>");

#Dec(66) #查询ascii码表对应可见字符B
#结论:所以输出了B



注:也就是说直接利用print之类的方法直接打印二进制字符串可能并没有什么实际意义。实际能打印出来的只是这些二进制对应的ascii码而已。

其实和python的pack/unpack本质上差不多。python使用struct处理二进制数据(使用pack和unpack进行打包和解包)_calcsize函数_焱齿的博客-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

焱齿

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值