PDF文件格式(一):交叉引用流

在PDF-1.5版本之前,对象的交叉引用信息是存储在交叉引用表(cross-reference table)中的。在PDF-1.5版本之后,引进了交叉引用流(cross-reference stream)对象,可以用它来存储对象的交叉引用信息,就像交叉引用表的功能一样。

采用交叉引用流对象有以下几点好处:

1) 存储的信息更紧凑,并且可以引入压缩算法进行压缩

2) 提供了访问存储于对象流(ObjectStreams)中的被压缩的对象的功能

3) 提供了将来的可扩展的交叉引用流的表项类型,以便存储更多不同信息

PDF交叉引用表是PDF的重要组成部分,本文介绍的是交叉引用流(cross-reference stream)对象,这种引用表的格式是PDF的obj格式,内容是被压缩存放在obj下的stream中,因此比常规的引用表格式复杂。下面就开始介绍这种交叉引用表的格式和解析的方法:

1 定位最初始位置:

交叉引用表方法一样,需要到文件尾部找到"startxref"后面的数字,就是第一个交叉引用表的位置(PDF交叉引用表是倒序的,应该说是最后一个)。

2 解析交叉引用表obj内容:

取出obj内DecodeParms,W, Index,size,Prev ,stream内容

DecodeParms是解压缩参数,针对当前Obj有stream内容的情形,解压缩stream内容使用(解压缩部分后续再说)

W的值是数组,数组里面有三个数字,表示的是交叉引用表三个元素(type,file offset,generation)信息在stream内容需要读取的长度;

Index的值也是数组,数量是偶数个,两两一组,表示交叉引用对应obj的起始obj号和范围;

Prev的值是下一个交叉引用表的位置(准确的说应该叫上一个,因为PDF交叉引用表是倒序的,为了描述方便);

stream的内容是交叉引用表的实际内容,交叉引用相关信息被处理,再被压缩

3 多个交叉引用表

 当文档内有多个交叉引用表时,当前引用表obj的prev内容保存的是下一个交叉引用表的位置,如果当前引用表时最后一个,那么当前obj找不到Prev。

在解析多个交叉引用表时,需要不断查找当前obj下是否存在prev,如果不存在,则停止查找,说明交叉引用表到此是最后一个,在交叉引用表尾都会部有startxrf字段,后面的数字就是当前交叉引用表位置。因此,在最开头去文件尾部查找startxrf,也是在查找第一个交叉引用表尾部的startxrf。

这里第一个引用表的Prev是541882,找到541882(0x844ba)位置如下:

105 0 obj仍然是交叉引用表obj,里面还有Prev,在endobj后面跟着startxrf(当前交叉引用表位置)。

注意:有时候startxrf记录的不是当前obj的位置,准确的方式是使用引用表obj内的Prev判断。

下面结合实例,看一下交叉引用表时如何被解析出来的:

这是一段PDF文档内容:

可以看到,在PDF尾部的startxrf的是572618,对应的位置是8bcca,正好是116 0 obj,这里的Index是[1 1 4 1 12 1 106 11],表示这段交叉引用表保存的是1号obj,4号obj,12号obj,106号至117(106+11)号obj(106,107,108,109....117);W是[1 3 0];接下来是stream内容,下面是一段解压之后的stream内容:

第一个字节是type内容,0表示f,1表示n,2表示o;2到4字节是offset值,二进制存储,得到结果是542265,最后由于W数组最后一个是0,所以不读取stream数据,generation值为0;从stream起始位置对应Index的顺序(两两一组)最后得出交叉引用表的信息:1号obj,type是n,位置在542265,generation是0,;好了现在找到了交叉引用表的1号obj,我们到542265位置看一下:

可以看到,0x84639对应的位置正是1 0 obj,这样一个完整的交叉引用表流程解析完毕。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/252899.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小白代码审计入门

最近小白一直在学习代码审计,对于我这个没有代码审计的菜鸟来说确实是一件无比艰难的事情。但是着恰恰应了一句老话:万事开头难。但是小白我会坚持下去。何况现在已经喜欢上了代码审计,下面呢小白就说一下appcms后台模板Getshell以及读取任意文件,影响的版本是2.0.101版本。…

Pyhton专项进阶——http协议、cookie、session和认证-3

关于cookie的报文首部相关属性熟悉后,下面就是实际应用。 使用cookie实现用户登录验证(初步): 思路(一):显示登录页面,输入用户和密码,后端验证,如果验证通…

【TCP】四次挥手(终止连接)

前言 TCP(传输控制协议)是互联网协议(IP)中的一种重要传输层协议,用于在通信的计算机之间建立可靠的、有序的和错误校验的数据传输。在TCP连接中,数据传输是双向的,因此需要一种机制来开始和结…

Mac上新版InfluxDB使用教程

一、简介 官网:influxdb 二、influxdb安装 建议使用Homebrew在 macOS 上安装 InfluxDB v2: brew install influxdb启动influxdb服务:brew services start influxdb 停止influxdb服务:brew services stop influxdb 查看是否启…

docker 运行jar包 指定配置文件

要在Docker中运行JAR包并指定配置文件,你可以创建一个Dockerfile来定义你的容器环境,并在其中指定如何运行JAR包和配置文件。下面是一个简单的例子,展示了如何在Dockerfile中设置这些配置: 第一步:创建 Dockerfile文件…

《MySQL》超详细笔记

目录 基本知识 主流数据库 数据库基本概念 MySQL启动 数据库基本命令 数据库 启动数据库 显示数据库 创建数据库 删除数据库 使用数据库 查询当前数据库信息 显示数据库中的表 导入数据库脚本 表 查看表的结构 查看创建某个表的SQL语句 数据库的查询命令 查询…

人工智能(pytorch)搭建模型24-SKAttention注意力机制模型的搭建与应用场景

大家好,我是微学AI,今天给大家介绍一下人工智能(pytorch)搭建模型24-SKAttention注意力机制模型的搭建与应用场景,本文将介绍关于SKAttention注意力机制模型的搭建,SKAttention机制具有灵活性和通用性,可应用于计算机视…

canvas缩放坐标系(scale)

查看专栏目录 canvas实例应用100专栏,提供canvas的基础知识,高级动画,相关应用扩展等信息。canvas作为html的一部分,是图像图标地图可视化的一个重要的基础,学好了canvas,在其他的一些应用上将会起到非常重…

2024最新版鸿蒙HarmonyOS开发工具安装使用指南

2024最新版鸿蒙HarmonyOS开发工具安装使用指南 By JacksonML 0. 什么是鸿蒙Harmony OS? 华为鸿蒙系统(HUAWEI Harmony OS),是华为公司在2019年8月9日于东莞举行的华为开发者大会(HDC.2019)上正式发布的分…

Java20:新特性

一:Lambda表达式: 1. Lambda表达式使用前后对比: 举类一: Testpublic void test(){ Runnable r1 new Runnable() {Overridepublic void run() {System.out.println("我爱北京天安门!");} };r1.run();Syst…

基于SSM的协同过滤技术的网上书城(有报告)。Javaee项目。ssm项目。

演示视频: 基于SSM的协同过滤技术的网上书城(有报告)。Javaee项目。ssm项目。 项目介绍: 采用M(model)V(view)C(controller)三层体系结构,通过Sp…

手撕spring bean的加载过程

这里我们采用手撕源码的方式,开始探索spring boot源码中最有意思的部分-bean的生命周期,也可以通过其中的原理理解很多面试以及工作中偶发遇到的问题。 springboot基于约定大于配置的思想对spring进行优化,使得这个框架变得更加轻量化&#…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Radio组件

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之Radio组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、Radio组件 单选框,提供相应的用户交互选择项。 子组件 无。 接口 …

第十五篇【传奇开心果系列】Python的OpenCV库技术点案例示例:图像配准

传奇开心果短博文系列 系列短博文目录Python的OpenCV库技术点案例示例系列短博文目录前言一、常见的图像配准任务介绍二、图像配准任务:图像拼接介绍和示例代码三、图像配准任务:图像校正介绍和示例代码四、图像配准任务:图像配准介绍和示例代码五、基于特征点的配准方法介绍…

面试150 颠倒二进制位 位运算分治 逻辑右移

Problem: 190. 颠倒二进制位 文章目录 思路复杂度位运算分治法 思路 👨‍🏫 参考题解 >>>:逻辑右移(符号位一起移动,高位补零) 复杂度 时间复杂度: O ( log ⁡ n ) O(\log{n}) O(logn) 空间…

Nacos1.X源码解读(待完善)

下载源码 1. 克隆git地址到本地 # 下载nacos源码 git clone https://github.com/alibaba/nacos.git 2. 切换分支到1.4.7, maven编译(3.5.1) 3. 找到启动类com.alibaba.nacos.Nacos 4. 启动VM参数设置单机模式, RUN 启动类 -Dnacos.standalonetrue 5. 启动本地服务注册到本…

3、生成式 AI 如何帮助您改进数据可视化图表

生成式 AI 如何帮助您改进数据可视化图表 使用生成式 AI 加速和增强数据可视化。 图像来源:DALLE 3 5 个关键要点: 数据可视化图表的基本结构使用 Python Altair 构建数据可视化图表使用 GitHub Copilot 加快图表生成速度使用 ChatGPT 为您的图表生成相关内容使用 DALL-E 将…

elementPlus实现动态表格单元格合并span-method方法总结

最近在做PC端需求的时候,需要把首列中相邻的同名称单元格合并。 我看了一下elementPlus官网中的table表格,span-method可以实现单元格合并。 我们先看一下官网的例子: 合并行或列 多行或多列共用一个数据时,可以合并行或列。 …

IDEA生成可执行jar包

1. 进入需要打包的项目,选择 最上方菜单栏的 File → Project Structure 2. 选择 左侧菜单栏 Artifacts → 加号 → JAR → from modules with dependencies 3. 选择入口类 Main Class(点击文件夹图标可以快速选择),点击 OK&#…

go语言每日一练——链表篇(六)

传送门 牛客面试必刷101题—— 判断链表中是否有环 牛客面试必刷101题—— 链表中环的入口结点 题目及解析 题目一 代码 package mainimport . "nc_tools"/** type ListNode struct{* Val int* Next *ListNode* }*//**** param head ListNode类* return bool…