尝试使用 pack 与 unpack 函数

今天接触了两个比较冷门的函数 packunpack,查阅了相关资料,想和大家分享一下,这两个函数是处理 字节 的函数,首先再梳理了一下它们的关系。

字节和字符

日常工作学习中,与 字符串 接触比较多,但字符的伴生概念:字节,我不太熟悉。

它们之间有什么区别呢?

简单来说 字节 是计算机存储和操作的最小单位,字符 是人们阅读的最小单位;字节 是存储(物理)概念,字符 是逻辑概念;字节 代表数据(内涵和本质),字符 代表其含义;字符字节 组成。好像有点绕。

比如说:咱们的首都,”北京” 包含 2 个字符,在 UTF-8 编码格式下它需要 6 个字节,数字 “666666”,包含 6 个字符,用 int 类型表示只需要 4 个字节。

字节处理函数

PHP 内置的字符串函数有非常多,但是字节处理函数比较少,今天接触了 packunpack,想和大家一起再学习学习。

pack

作用

将数据打包成二进制字符串

使用

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

参数

  • format 这个参数由格式代码组成,紧跟着一个可选的重复参数(可以是一个整数值或用 * 来表示重复到输入数据的末尾),对于 aAhH 来说此参数指定了给定数据会被使用几个字符串,对于 @ 来说其后的数字表示放置剩余数据的绝对定位(之前的会被空字符串填充),对于其他内容,重复数量指定消耗多少数据进行 pack 操作。
  • args

返回值

返回包含数据的二进制字符串。

例子

var_dump(pack('C', 80))
var_dump(pack('C*', 80, 72, 80)) 

"P"
"PHP"

unpack

作用

从二进制字符串中解压缩数据

使用

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

参数

  • format 参阅上面的 pack
  • data 想要释放的数据
  • offset 从何处开始释放

返回值

返回包含二进制字符串的解压缩元素的关联数组。

例子

var_dump(unpack('C', 'P'))
var_dump(unpack('C*', 'PHP')) 

[ 
    1 => 80,
]

[ 
    1 => 80, 
    2 => 72, 
    3 => 80,
]

有一点需要注意。

unpack('H*hello/C*world', 'PHP')

[
     "hello" => "504850",
     "world1" => 80,
     "world2" => 72,
     "world3" => 80,
]

unpack('H*/C*', 'PHP')

[
     1 => 80,
     2 => 72,
     3 => 80,
]

为啥会这样呢?文档是这么说的

Caution
If you do not name an element, numeric indices starting from 1 are used. Be aware that if you have more than one unnamed element, some data is overwritten because the numbering restarts from 1 for each element.

意思是说,如果我们不对数据命名,默认使用从 1 开始的数字索引,所以如果不命名,后面的会覆盖前面的数据。

总结

虽然这两个函数用的极少,但是还是在某些场景能用上。

在琢磨 redis 位运算统计的时候,琢磨把二进制字符串解压缩数据,就用上了嘛!

$pack = unpack('C*', '\x00\x10')

$tmp = array_map(function ($val) {
        $val = base_convert($val, 10, 2);
        $val = str_pad($val, 8, 0, STR_PAD_LEFT);
        return $val;
    }, $pack);

echo implode(' ', $tmp);

01011100 01111000 00110000 00110000 01011100 01111000 00110001 00110000

参考资料

ASCII
pack函数
unpack函数
base_convert函数
PHP中的pack和unpack函数
如何利用 Redis 快速实现签到统计功能
Redis 中 BitMap 是如何储存的,以及 PHP 如何处理

最后

这是我潜伏这么久以来,第一次尝试书写文章,可能不通顺,大家见谅哈。

还要感谢 OvertrueLhao 两位帅哥!

本作品采用《CC 协议》,转载必须注明作者和本文链接
Hello。
本帖由系统于 3年前 自动加精
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 2
finecho

优秀,哈哈

5年前 评论

@Lhao :kiss:

5年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!