[[IT知识]] 揭秘PHP读取与解析PNG文件头的奥秘

[复制链接]
查看: 29|回复: 0
发表于 2025-2-12 09:40:01 | 显示全部楼层 | 阅读模式
易博V9下载

揭秘PHP读取与解析PNG文件头的奥秘

很多时候,数据并不是用文本的方式保存的,这就需要将二进制数据读取出来,还原成我们需要的格式。在二进制处理方面也提供了强大的支持。

任务

下面以读取并分析一个PNG图像的文件头为例,讲解如何使用PHP读取和分析二进制文件。

涉及函数

fopen

fread

unpack

bin2hex

PNG格式简介

为了完成任务,下面简单介绍一下PNG文件格式。

PNG是一种无损压缩的图像文件格式,该格式的第1-8字节保存着PNG署名域,内容如下:

十进制: 137 80 78 71 13 10 26 10

十六进制: 89 50 4e 47 0d 0a 1a 0a

我们的任务就是将这个文件头读取出来。

更详细的关于PNG格式的介绍:

* PNG官方文档

* PNG官方网站

读取文件

  1. PHP代码
  2. $filePath = "icon.png"; // 必须使用rb来读取文件,这样能保证跨平台二进制数据的读取安全
  3. $fh = fopen($filePath, "rb");
  4. // 仅读取前面的8个字节
  5. $head = fread($fh, 8);
  6. fclose($fh);
复制代码

上面的代码已经把我们需要的8个字节读入变量head中了。head是一个保存二进制数据的数组,我们还需要对它做一些操作才能得到我们需要的数据。

unpack

unpack可以将二进制数据解析成关系数组,它接受2个参数,第一个提供解析方式字符串(见下方),第二个参数就提供我们前面读出的head变量就可以了。

a:NULL填充的字节串

A:空格填充的字节串

h:十六进制数,低四位字节优先

H:十六进制数,高四位字节优先

c:有符号字符

C:无符号字符

s:有符号短整型(总是16位,机器字节序)

S:无符号短整型(总是16位,机器字节序)

n:无符号短整型(总是16位,大尾字节序)

v:无符号短整型(总是16位,小尾字节序)

I:无符号整型(机器相关大小和字节序)

l:有符号长整型(总是32位,机器字节序)

L:无符号长整型(总是32位,机器字节序)

N:无符号长整型(总是32位,大尾字节序)

V:无符号长整型(总是32位,小尾字节序)

f:浮点数(机器相关大小和表示)

d:双精度数(机器相关大小和表示)

x:空字节

X:倒退一个字节

@:用NULL填充绝对位置

unpack的第一个参数在在使用上有一点点小技巧,下面是范例:

C 读取1个字符,返回的数组索引为1

C4 读取4个字节,每个字节一个字符,返回的数组索引为1,2,3,4

C4head 读取4个字符,每个字节一个字符,返回的数组索引为head1,head2,head3,head4

Chead 读取1个字符,返回的数组索引为head

现在试着读取第1个字节:

  1. PHP代码
  2. $arr = unpack("Chead", $head);
  3. print_r($arr);
  4. // Array ( [head] => 137 )
复制代码

读取所有的8个字节,用斜杠可以分隔:

  1. PHP代码
  2. $arr = unpack("Chead/C3string/C4number", $head);
  3. print_r($arr);
  4. // Array ( [head] => 137 [string1] => 80 [string2] => 78 [string3] => 71 [number1] => 13 [number2] => 10 [number3] => 26 [number4] => 10 )
复制代码

把string开头的键拼成字符串:

  1. PHP代码
  2. $arr = unpack("Chead/C3string/C4number", $head);
  3. for($i=1;$i<=3;$i++)
  4. {
  5. $type.=chr($arr['string'.$i]);
  6. }
  7. echo $type;
  8. // PNG
复制代码

bin2hex

上面使用print_r打印出来的内容,都是十进制数字,如果希望直接得到十六进制值,可以使用bin2hex函数。

  1. PHP代码
  2. echo bin2hex($head[0]);
  3. // 89
复制代码

注意,使用这种方法得到的是字符串,并不是数字。因此下面的条件是不成立的:

  1. PHP代码
  2. if(bin2hex($head[0]) == "89")
  3. {
  4. echo 'match!';
  5. }
复制代码
易博软件介绍
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

1、请认真发帖,禁止回复纯表情,纯数字等无意义的内容!帖子内容不要太简单!
2、提倡文明上网,净化网络环境!抵制低俗不良违法有害信息。
3、如果你对主帖作者的帖子不屑一顾的话,请勿回帖。谢谢合作!
3、问答求助区发帖求助后,如有其他用户热心帮您解决问题后,请自觉点击设为最佳答案按钮。

 
 
QQ在线客服
QQ技术支持
工作时间:
8:00-18:00
软著登字:
1361266号
官方微信扫一扫
weixin

QQ|小黑屋|Archiver|慈众营销 ( 粤ICP备15049986号 )|网站地图

自动发帖软件 | 自动发帖器 | 营销推广软件 | 网络营销工具 | 网络营销软件 | 网站推广工具 | 网络推广软件 | 网络推广工具 | 网页推广软件 | 信息发布软件 | 网站推广工具 | 网页推广软件

Powered by Discuz! X3.4   © 2012-2020 Comsenz Inc.  慈众科技 - Collect from 深圳吉宝泰佛文化有限公司 公司地址:罗湖区黄贝街道深南东路集浩大厦A1403

返回顶部 返回列表