当前位置: 首页 > news >正文

PHP中pack、unpack的用法

pack
string pack ( string $format [, mixed $args [, mixed $... ]] )
该函数用来将对应的参数($args)打包成二进制字符串。

其中第一个参数$format,有如下选项:
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    双精度浮点型(机器相关大小)
x    NUL字节
X    回退一字节
Z    以NUL字节填充字符串空白(new in PHP 5.5)
@    NUL填充到绝对位置


高/低位字节
比如字符串AB,左高右低,A为高字节,B为低字节

高/低地址
假设0x123456是按从高位到底位的顺序储存,内存中是这样存放的:

高地址 -> 低地址
12 -> 34 -> 56

大端字节序(网络字节序)
大端就是将高位字节放到内存的低地址端,低位字节放到高地址端。网络传输中(比如TCP/IP)低地址端(高位字节)放在流的开始,对于2个字节的字符串(AB),传输顺序为:A(0-7bit)、B(8-15bit)。
那么小端字节序自然和大端相反。

主机字节序
表示当前机器的字节序(网络字节序是确定的,主机字节序是依机器确定的),一般为小端字节序。

a和A(打包字符串,用NUL或者空格填充)
$string = pack('a6', 'china');
var_dump($string); //输出结果: string(6) "china",最后一个字节是不可见的NUL
echo ord($string[5]); //输出结果: 0(ASCII码中0对应的就是nul)

//A同理
$string = pack('A6', 'china');
var_dump($string); //输出结果: string(6) "china ",最后一个字节是空格
echo ord($string[5]); //输出结果: 32(ASCII码中32对应的就是空格)

h和H
$string = pack('H3', 281);
var_dump($string); //输出结果: string(2) "("

for($i=0;$i<strlen($string);$i++) {
echo ord($string[$i]) . PHP_EOL;
}
//输出结果: 40 16

h和H需要特殊说明一下,它们是将对应的参数看做十六进制字符然后打包。什么意思呢?比如上面的281,打包前会将281转换为0x281,因为十六进制的一位对应二进制的四位,上面的0x281只有1.5个字节,后面会默认补0变成0x2810,0x28对应的十进制为40((),0x10对应的十进制为16(dle不可见字符),懂了吧?不懂可以给我留言。。

c和C
$string = pack('c3', 67, 68, -1);
var_dump($string); //输出:string(3) "CD�"

for($i=0;$i<strlen($string);$i++) {
echo ord($string[$i]) . PHP_EOL;
}
//输出: 67 68 255

最后输出本能应该觉得是67 68 -1
ord获取的是字符的ASCII码(范围0-255),这时-1(0000 0001)对应的字符将以补码的形式输出也就是255(1111 1110 + 0000 0001 = 1111 1111)

整型相关
所有的整型类型使用方法完全一样,主要注意它们的位和字节序就可以了,下面以L作为例子展示

$string = pack('L', 123456789);
var_dump($string); //输出:string(4) "�["

for($i=0;$i<strlen($string);$i++) {
echo ord($string[$i]) . PHP_EOL;
}
//输出: 21 205 91 7

f和d
$string = pack('f', 12345.123);
var_dump($string);
//输出:string(4) "~�@F"
var_dump(unpack('f', $string)); //这里提前用到了unpack,后面会讲解
//输出:float(12345.123046875)

f和d是针对浮点数打包,至于为什么打包前是12345.123解包后是12345.123046875,这个和浮点数的储存有关系

x、X、Z、@
$string = pack('x'); //打包一个nul字符串
echo ord($string); //输出: 0

关于X(大写X),试了N次,没搞明白怎么用,有清楚的童鞋可以给我留言,多谢。

$string = pack('Z2', 'abc5'); //其实就是将从Z后面的数字位置开始,全部设置为nul
var_dump($string); //输出:string(2) "a"

for($i=0;$i<strlen($string);$i++) {
echo ord($string[$i]) . PHP_EOL;
}
//输出: 97 0

$string = pack('@4'); //我理解为填充N个nul
var_dump($string); //输出: string(4) ""

for($i=0;$i<strlen($string);$i++) {
echo ord($string[$i]) . PHP_EOL;
}
//输出: 0 0 0 0

unpack
array unpack ( string $format , string $data )


unpack的使用相当简单,就是讲pack打包的数据解包,打包的时候用的什么参数,就用什么参数解包,具体使用懒得说了,列几个小例子

$string = pack('L4', 1, 2, 3, 4);
var_dump(unpack('L4', $string));
//输出:
array(4) {
[1]=>
int(1)
[2]=>
int(2)
[3]=>
int(3)
[4]=>
int(4)
}

$string = pack('L4', 1, 2, 3, 4);
var_dump(unpack('Ll1/Ll2/Ll3/Ll4', $string)); //可以指定key,用/分割
//输出:
array(4) {
["l1"]=>
int(1)
["l2"]=>
int(2)
["l3"]=>
int(3)
["l4"]=>
int(4)
}

这两个函数到底有啥用途?
数据通信(通过二进制格式与其它语言通信)
数据加密(如果不告诉第三方你的打包方式,对方解包的难度就相对很大)
节省空间(比如比较大的数字按字符串储存会浪费很多空间,打包成二进制格式才需要4位<32位数字>)
 

相关文章:

PHP中pack、unpack的用法

pack string pack ( string $format [, mixed $args [, mixed $... ]] ) 该函数用来将对应的参数($args)打包成二进制字符串。 其中第一个参数$format&#xff0c;有如下选项&#xff1a; a 以NUL字节填充字符串空白 A 以SPACE(空格)填充字符串 h 十六进制字符串&…...

KUKA机器人零点标定的具体方法

KUKA机器人零点标定的具体方法 在进行机器人校正时,先将各轴置于一个定义好的机械位置,即所谓的机械零点。这个机械零点位置表明了同轴的驱动角度之间的对应关系,它用一个测量刻槽表示。 为了精确地确定机器人某根轴的机械零点位置,一般应先找到其预校正位置,然后去掉测量…...

基于SpringBoot+Vue的旅游系统

摘 要 随着旅游业的发展&#xff0c;越来越多的人选择旅游作为自己的出行方式。在旅游规划过程中&#xff0c;旅游景点选择是至关重要的环节。本文提出了一种基于协同过滤推荐算法的旅游平台系统。该系统采用前后端分离的设计&#xff0c;主要使用了SpringBoot、Vue等技术&…...

leetcode算法题--复杂链表的复制

原题链接&#xff1a;https://leetcode.cn/problems/fu-za-lian-biao-de-fu-zhi-lcof/description/?envTypestudy-plan-v2&envIdcoding-interviews 感觉一开始想到的办法还是比较笨 /*** Definition for a Node.* type Node struct {* Val int* Next *Node* …...

C++面试题(叁)---操作系统篇

目录 操作系统篇 1 Linux中查看进程运行状态的指令、查看内存使用情况的指令、 tar解压文件的参数。 2 文件权限怎么修改 3 说说常用的Linux命令 4 说说如何以root权限运行某个程序。 5 说说软链接和硬链接的区别。 6 说说静态库和动态库怎么制作及如何使用&#xff0c;区…...

算法笔记:KD树

1 引入原因 K近邻算法需要在整个数据集中搜索和测试数据x最近的k个点&#xff0c;如果一一计算&#xff0c;然后再排序&#xff0c;开销过大 引入KD树的作用就是对KNN搜索和排序的耗时进行改进 2 KD树 2.1 主体思路 以空间换时间&#xff0c;利用训练样本集中的样本点&…...

plumelog介绍与应用-一个简单易用的java分布式日志系统

官方文档&#xff1a;http://www.plumelog.com/zh-cn/docs/FASTSTART.html 简介 无代码入侵的分布式日志系统&#xff0c;基于log4j、log4j2、logback搜集日志&#xff0c;设置链路ID&#xff0c;方便查询关联日志基于elasticsearch作为查询引擎高吞吐&#xff0c;查询效率高全…...

百度网盘删除“我的应用数据”文件夹

百度网盘删除“我的应用数据”文件夹电脑端方法-2023.2.27成功 - 哔哩哔哩 (bilibili.com) 百度网盘怎样删除我的应用数据文件夹-手机端方法-2023.3.24日成功 - 哔哩哔哩 (bilibili.com)...

多店铺智能客服,助力店铺销量倍增

近年来电商发展得非常快速&#xff0c;市场竞争也是愈发激烈了。商家不仅需要提高产品和服务的质量&#xff0c;还要争取为自己获取更多的曝光&#xff0c;以此来分散运营的风险和降低经营的成本&#xff0c;所以越来越多的商家也开始转向多平台多店铺运营。但即使运营多个平台…...

会话跟踪技术

cookie 是通过在浏览器第一次请求服务器时&#xff0c;在响应中放入cookie&#xff0c;浏览器接收到cookie后保存在本地&#xff0c;之后每次请求服务器时都将cookie携带到请求头中&#xff0c;用来验证用户身份与状态等。 缺点&#xff1a; 移动端app没有cookiecookie保存在…...

递归算法学习——子集

目录 一&#xff0c;题目解析 二&#xff0c;例子 三&#xff0c;题目接口 四&#xff0c;解题思路以及代码 1.完全深度搜索 2.广度搜索加上深度优先搜索 五&#xff0c;相似题 1.题目 2.题目接口 3.解题代码 一&#xff0c;题目解析 给你一个整数数组 nums &#xff0c…...

学习笔记:ROS使用经验(ROS报错)

报错&#xff1a;进程崩溃 ] process has died [pid 734, exit code -5, cmd /root/catkin_ws/devel/lib/pose_graph/pose_graph __name:pose_graph __log:/root/.ros/log/31b0ae1c-3295-11ee-bda9-02429b5737dc/pose_graph-5.log]. log file: /root/.ros/log/31b0ae1c-3295-11…...

设计模式二十四:访问者模式(Visitor Pattern)

用于将数据结构与数据操作分离&#xff0c;使得可以在不修改数据结构的情况下&#xff0c;定义新的操作。访问者模式的核心思想是&#xff0c;将数据结构和操作进行解耦&#xff0c;从而使得新增操作时不必修改数据结构&#xff0c;只需添加新的访问者。主要目的是在不改变数据…...

使用gn+Ninja构建项目

使用下载编译好的gn和ninja报错 先下载了gn的源码[gn.googlesource.com/gn]&#xff0c;然后编译报错&#xff0c;就直接下载了了编译号的gn和Ninja&#xff0c;然后写了Helloworld应用的BUILD.gn&#xff0c;然后将"gn\examples\simple_build\build"拷贝至当前目录…...

VMware虚拟机连不上网络

固定ip地址 进入网络配置文件 cd /etc/sysconfig/network-scripts 打开文件 vi ifcfg-ens33 编辑 BOOTPROTO设置为static&#xff0c;有3个值&#xff08;decp、none、static&#xff09; BOOTPROTO"static" 打开网络 ONBOOT"yes" 固定ip IPADDR1…...

安防视频监控/视频集中存储/云存储平台EasyCVR平台无法取消共享通道该如何解决?

视频汇聚/视频云存储/集中存储/视频监控管理平台EasyCVR能在复杂的网络环境中&#xff0c;将分散的各类视频资源进行统一汇聚、整合、集中管理&#xff0c;实现视频资源的鉴权管理、按需调阅、全网分发、云存储、智能分析等&#xff0c;视频智能分析平台EasyCVR融合性强、开放度…...

算法通关村-----如何基于数组和链表实现栈

实现栈的基本方法 push(T t)元素入栈 T pop() 元素出栈 Tpeek() 查看栈顶元素 boolean isEmpty() 栈是否为空 基于数组实现栈 import java.util.Arrays;public class ArrayStack<T> {private Object[] stack;private int top;public ArrayStack() {this.stack new…...

day-05 TCP半关闭 ----- DNS ----- 套接字的选项

一、优雅的断开套接字连接 之前套接字的断开都是单方面的。 &#xff08;一&#xff09;基于TCP的半关闭 Linux的close函数和windows的closesocket函数意味着完全断开连接。完全断开不仅不能发送数据&#xff0c;从而也不能接收数据。在某些情况下&#xff0c;通信双方的某一方…...

区块链金融项目怎么做?

区块链技术的兴起引发了金融领域的变革&#xff0c;为金融行业带来了前所未有的机遇与挑战。在这个快速发展的领域中&#xff0c;如何在区块链金融领域做出卓越的表现&#xff1f;本文将从专业性和思考深度两个方面&#xff0c;探讨区块链金融的发展路径&#xff0c;并为读者提…...

Redis与数据库保持一致

参考链接 先更新数据库&#xff0c;再更新redis 存在漏洞&#xff0c;如果更新Redis失败&#xff0c;仍然会导致不一致 先删Redis&#xff0c;再更新数据库并同步数据到Redis 存在漏洞&#xff0c;多线程情况下,线程1删除redis后&#xff0c;还是有可能被其他线程读取旧的数据…...

python打卡day49

知识点回顾&#xff1a; 通道注意力模块复习空间注意力模块CBAM的定义 作业&#xff1a;尝试对今天的模型检查参数数目&#xff0c;并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试

作者&#xff1a;Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位&#xff1a;中南大学地球科学与信息物理学院论文标题&#xff1a;BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接&#xff1a;https://arxiv.…...

将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?

Otsu 是一种自动阈值化方法&#xff0c;用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理&#xff0c;能够自动确定一个阈值&#xff0c;将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

08. C#入门系列【类的基本概念】:开启编程世界的奇妙冒险

C#入门系列【类的基本概念】&#xff1a;开启编程世界的奇妙冒险 嘿&#xff0c;各位编程小白探险家&#xff01;欢迎来到 C# 的奇幻大陆&#xff01;今天咱们要深入探索这片大陆上至关重要的 “建筑”—— 类&#xff01;别害怕&#xff0c;跟着我&#xff0c;保准让你轻松搞…...

Vite中定义@软链接

在webpack中可以直接通过符号表示src路径&#xff0c;但是vite中默认不可以。 如何实现&#xff1a; vite中提供了resolve.alias&#xff1a;通过别名在指向一个具体的路径 在vite.config.js中 import { join } from pathexport default defineConfig({plugins: [vue()],//…...

面试高频问题

文章目录 &#x1f680; 消息队列核心技术揭秘&#xff1a;从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"&#xff1f;性能背后的秘密1.1 顺序写入与零拷贝&#xff1a;性能的双引擎1.2 分区并行&#xff1a;数据的"八车道高速公路"1.3 页缓存与批量处理…...

针对药品仓库的效期管理问题,如何利用WMS系统“破局”

案例&#xff1a; 某医药分销企业&#xff0c;主要经营各类药品的批发与零售。由于药品的特殊性&#xff0c;效期管理至关重要&#xff0c;但该企业一直面临效期问题的困扰。在未使用WMS系统之前&#xff0c;其药品入库、存储、出库等环节的效期管理主要依赖人工记录与检查。库…...

JS红宝书笔记 - 3.3 变量

要定义变量&#xff0c;可以使用var操作符&#xff0c;后跟变量名 ES实现变量初始化&#xff0c;因此可以同时定义变量并设置它的值 使用var操作符定义的变量会成为包含它的函数的局部变量。 在函数内定义变量时省略var操作符&#xff0c;可以创建一个全局变量 如果需要定义…...