PNG图片隐写之IDAT

embedded/2024/11/20 6:14:06/

IDAT__1">IDAT 结构

在PNG文件中,每个块(包括IDAT块)的结构是固定的,CRC校验码总是位于每个块的末尾。具体来说,每个块的结构如下:

长度(4字节):表示数据部分的长度。

类型(4字节):表示块的类型,如IHDR、IDAT、IEND等。

数据(可变长度):块的具体内容。

CRC(4字节):用于校验数据的完整性。

IDAT 的结尾标识是 IEND

IDAT 块数据表示含义

样例数据如下: 最开始 00 00 00 00不需要关注,是其他的信息

00 00 FF F4是第一个 IDAT 的长度。这个长度的计算不包含本身、IDAT、CRC 校验值,仅代表数据的长度。

49 44 41 54表示 IDAT 字符。

从 第一行的 35 7A C6 5C 到第 10 行的 A2 BF 1E 94 是数据本身, 长度就是计算的这个。

第 11 行 的 第二个块 IDAT 的长度 00 00 FF F4之前的四个字节 87 6E FA 22表示第一个 IDAT 的 CRC 校验。

最前面的 1:0000h 表示 如下:

1: 第 1 个 IDAT

0000h: 表示开始的长度。

         0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
1:0000h: 00 00 00 00 00 00 FF F4 49 44 41 54 35 7A C6 5C  ......ÿôIDAT5zÆ\ 
1:0010h: 49 A3 06 56 A7 2D 44 F9 C6 F9 4F 95 A1 60 24 A7  I£.-DùÆùO•¡`$§ 
1:0020h: 84 4D E0 EB 76 A0 49 A7 06 6A 67 05 5E CF 83 FE  „Màëv I§.jg.^σþ 
1:0030h: 5E F6 29 1D 4B FA 99 22 20 C6 8E A3 72 86 FD EA  ^ö).Kú™" ÆŽ£r†ýê 
1:0040h: F0 36 F8 06 F5 3C 5F C9 64 12 C4 CF F3 34 E5 57  ð6ø.õ<_Éd.ÄÏó4åW 
1:0050h: 41 EE 4A 65 83 07 D2 8D BC 89 25 AD 68 DC AE F0  AîJeƒ.Ò
........................................................  ................
1:FFE0h: EE C4 85 87 38 76 75 21 16 A9 86 80 46 CE 3A C3  îÄ…‡8vu!.©†€FÎ:à 
1:FFF0h: 25 22 5E CA BF 87 46 C7 93 18 D8 4C A2 BF 1E 94  %"^Ê¿‡FÇ“.ØL¢¿.2:0000h: 87 6E FA 22 00 00 FF F4 49 44 41 54 57 62 4F B6  ‡nú"..ÿôIDATWbO2:0010h: D0 5B 8B 8C 97 FE 63 3E 73 FE 63 CC F1 FD 1A 20  Ð[‹Œ—þc>sþcÌñý.  
2:0020h: 1B B3 7A 3B 02 E4 60 62 C8 F1 BB 72 DB C7 31 79  .³z;.ä`bÈñ»rÛÇ1y 

IDAT 的长度错误时,就会导致图片无法正常显示,IDAT 的长度最长是 231 - 1字节, 转化为 16 进制是

-1 字节的原因是,索引为 0 开始.

计算 IDAT 长度

还是上面的数据,拿过来计算,

我们只需要将数据的最后地址 - 最开始的地址即可。

很明显第 10 行的 A2 BF 1E 94是第一个 IDAT 块的结束。而其中 94的地址,通过左侧和最上方的地址能够看出来是 0xFFFF

而第一行数据的开始是 35 7A C6 5C,其中 35的地址是 0x0C

0xFFFF- 0x0C= 0xFFF310 进制是 65523,因为索引从 0 开始,所以最后长度还要 +1,得到第一个 IDAT 的长度为 65524,16 进制是 0xFFF4,因为长度为 4 个字节一组,所以不够的补 0, 最终得到 00 00 FF F4

         0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F
1:0000h: 00 00 00 00 00 00 FF F4 49 44 41 54 35 7A C6 5C  ......ÿôIDAT5zÆ\ 
1:0010h: 49 A3 06 56 A7 2D 44 F9 C6 F9 4F 95 A1 60 24 A7  I£.-DùÆùO•¡`$§ 
1:0020h: 84 4D E0 EB 76 A0 49 A7 06 6A 67 05 5E CF 83 FE  „Màëv I§.jg.^σþ 
1:0030h: 5E F6 29 1D 4B FA 99 22 20 C6 8E A3 72 86 FD EA  ^ö).Kú™" ÆŽ£r†ýê 
1:0040h: F0 36 F8 06 F5 3C 5F C9 64 12 C4 CF F3 34 E5 57  ð6ø.õ<_Éd.ÄÏó4åW 
1:0050h: 41 EE 4A 65 83 07 D2 8D BC 89 25 AD 68 DC AE F0  AîJeƒ.Ò
........................................................  ................
1:FFE0h: EE C4 85 87 38 76 75 21 16 A9 86 80 46 CE 3A C3  îÄ…‡8vu!.©†€FÎ:à 
1:FFF0h: 25 22 5E CA BF 87 46 C7 93 18 D8 4C A2 BF 1E 94  %"^Ê¿‡FÇ“.ØL¢¿.2:0000h: 87 6E FA 22 00 00 FF F4 49 44 41 54 57 62 4F B6  ‡nú"..ÿôIDATWbO2:0010h: D0 5B 8B 8C 97 FE 63 3E 73 FE 63 CC F1 FD 1A 20  Ð[‹Œ—þc>sþcÌñý.  
2:0020h: 1B B3 7A 3B 02 E4 60 62 C8 F1 BB 72 DB C7 31 79  .³z;.ä`bÈñ»rÛÇ1y 

最后一个 IDAT

通过 16 进制编辑工具的搜索功能,能够快速定位到最后一个 IDAT 块的所在位置

先找到倒数第二个 IDAT 块的结尾,也就是最后一个 IDAT 块的开始,这里根据之前讲的格式,可以得到

D1 B6 DB 87是倒数第二个 IDAT 的 CRC 值, 00 00 9E D0是 最后一个 IDAT 的长度(不确定是否正确,需要计算)

49 44 41 54表示最后一个 IDAT 标识,59 E5 27 BE是数据的开始。

长度是不包含 CRC 和标识的,肯定也不包含上一个 IDAT 的内容,所以最后得到的值,我们需要** 减去 12 **。

IDAT 的结尾标识是 IEND

IEND块的结构如下:
长度:00 00 00 004字节),表示数据部分的长度为0。
类型:49 45 4E 444字节),表示这是一个IEND块。
数据:空(0字节)。
CRC:AE 42 60 824字节),IEND块的标准CRC值。

也就是说这里最后一个 IDAT 块的 CRC 值为 CE 10 F1 2B

那么它的长度就应该是 0x9EE4 - 0x0C + 0x01= 0x9ED9

最后得到结果

IDAT 块 CRC 检查

这里需要注意的一点是,当我们确定长度之后,最好验证下 CRC 校验的值,这里可以通过 010Editor 的脚本判断

也可以通过工具 pngcheck 确定

最后修复之后,图片完全显示正常,而且通过 pngcheck 检查,无问题


http://www.ppmy.cn/embedded/138988.html

相关文章

如何通过统计来反映工业新产业发展情况

工业战略性新兴产业对经济全局和长远发展具有重大引领带动作用&#xff0c;如何通过统计来反映工业新产业发展情况&#xff1f; 战略性新兴产业是以重大技术突破和重大发展需求为基础&#xff0c;对经济社会全局和长远发展具有重大引领带动作用&#xff0c;知识技术密集、物质…

在openi平台 基于华为顶级深度计算平台 openmind 动手实践

大家可能一直疑问&#xff0c;到底大模型在哪里有用。 本人从事的大模型有几个方向的业务。 基于生成式语言模型的海事航行警告结构化解析。 基于生成式语言模型的航空航行警告结构化解析。 基于生成式生物序列&#xff08;蛋白质、有机物、rna、dna、mrna&#xff09;的多模态…

国产RestApi工具Apifox使用介绍

常见RestApi工具介绍 常见的接口工具有Postman、Swagger等&#xff0c;当然还有其他很多种&#xff0c;就不列举了&#xff0c;在遇到Apifox之前&#xff0c;我一直都使用的Postman&#xff0c;但是Postman有个弊端&#xff0c;就是网络问题&#xff0c;还有就是免费有限制&…

HBase 开发:使用Java操作HBase

1、实战简介 HBase和Hadoop一样&#xff0c;都是用Java进行开发的&#xff0c;本次实训我们就来学习如何使用Java编写代码来操作HBase数据库。 实验环境&#xff1a; hadoop-2.7 JDK8.0 HBase2.1.1 2、任务 1、第1关&#xff1a;创建表 package step1; import java.io.IOE…

JavaScript 高级—求数组的最大值与最小值

JavaScript 数组操作&#xff1a;求数组的最大值与最小值 在编程中&#xff0c;处理数组是一个常见的任务。JavaScript 提供了一些内建的方法和技巧&#xff0c;可以方便地找到数组中的最大值和最小值。今天&#xff0c;我们就来详细探讨一下如何使用 JavaScript 来实现这一功…

读懂top后显示内容

第一行&#xff1a;系统信息 top - 06:33:12 up 42 min, 1 user, load average: 0.04, 0.02, 0.00 06:33:12&#xff1a;当前时间。up 42 min&#xff1a;系统已经启动了 42 分钟。1 user&#xff1a;当前有 1 个用户登录。load average: 0.04, 0.02, 0.00&#xff1a;这三个…

Flutter 生成二维码

在这篇博客中&#xff0c;我们将学习如何使用 Flutter 创建二维码&#xff0c;并实现一些常见的自定义选项。通过使用 qr_flutter插件&#xff0c;我们可以轻松地生成基本二维码&#xff0c;甚至可以将图片嵌入二维码中。最终的效果将包括两个二维码&#xff1a;一个是普通二维…

不一样的CSS(二)

目录 一、内容回顾 二、上节内容结束代码 三、icon图标之八卦图 1.内容展示 2.图形分析 3.代码展示 四、icon图标之爱心 1.效果展示 2.代码展示 3.原理分析 五、icon图标之导航图标 1.原理 2.代码实现 3.运行结果展示​编辑 六、icon图标之头像 1.原理分析&…