尝试使用 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 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 2
finecho

优秀,哈哈

5年前 评论

@Lhao :kiss:

5年前 评论

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