PDF字典的编码

PDF字典的编码,pdf,encoding,Pdf,Encoding,我需要知道PDF字典值的编码(不是向用户显示的文本,而是“代码隐藏”)。 我计划不使用任何图书馆。 在哪里可以找到它?您可以在PDF规范()中找到它。详细阐述一下你问题中最重要的几点 1) PDF字典可以包含多种值类型(布尔值、数字、字符串…)。您将遇到的编码取决于值的类型 2) 大多数情况下,有趣而复杂的情况是对象的类型是字符串 3) 对于字符串,请阅读PDF规范中的第7.9.2节。这说明了这些字符串可以使用什么编码(PDFDocEncoding、Unicode编码…),以及如何识别特定字符串

我需要知道PDF字典值的编码(不是向用户显示的文本,而是“代码隐藏”)。 我计划不使用任何图书馆。
在哪里可以找到它?

您可以在PDF规范()中找到它。详细阐述一下你问题中最重要的几点

1) PDF字典可以包含多种值类型(布尔值、数字、字符串…)。您将遇到的编码取决于值的类型

2) 大多数情况下,有趣而复杂的情况是对象的类型是字符串

3) 对于字符串,请阅读PDF规范中的第7.9.2节。这说明了这些字符串可以使用什么编码(PDFDocEncoding、Unicode编码…),以及如何识别特定字符串的编码

PDF字典值的编码

PDF字典的值是PDF对象

您应该查看PDF规范,特别是第7章语法,以了解PDF对象。你会发现:

分隔对象和描述PDF文件结构的标记应使用ASCII字符 设置此外,PDF标准词典和 应使用ASCII字符集定义某些类型的数组

因此,大多数情况下,您必须处理ASCII值

但是,字符串的情况很棘手,因为有几种类型的字符串使用相同的字符串语法选项,因此必须根据上下文解释它们的内容

表35–字符串对象类型

类型说明

文本字符串应用于人类可读的文本,如文本 注释、书签名称、文章名称和 文件信息。这些字符串应进行编码 使用PDFDOCENCODE或UTF-16BE与 前导字节顺序标记。 7.9.2.2“文本字符串类型”中描述了该类型

PDFDocEncoded字符串应用于 使用PDFDocencode以单个字节表示。 7.9.2.3“PDFDocEncoded字符串”中描述了这种类型 类型。“

ASCII字符串应用于以ASCII格式表示的字符 使用ASCII编码的单字节

字节字符串应用于表示为一系列字节的二进制数据 字节,其中每个字节可以是中可表示的任何值 8位。字符串可以表示字符,但 编码是未知的。字符串的字节不需要 表示字符。此类型应用于数据 例如MD5哈希值、签名证书和Web 捕获标识值。 7.9.2.4“字节字符串类型”中描述了这种类型

如果字符串是作者元数据的值,则它是文本字符串,因此使用PDFDOCENCODE或带前导字节顺序标记的UTF-16BE对其进行编码

另一方面,如果字符串是签名词典中的值,例如Contents,则它是一个包含二进制对象的字节字符串,则根据某种编码对其进行解释的任何尝试都将失败

对于streams,情况更为棘手

首先,可以以某种方式处理流内容,例如,可以对其进行压缩。要获得实际的流内容,首先必须撤消此处理

内容可以是二进制(例如字体程序)或文本(例如JavaScript),也可以是内容流(例如页面内容)

内容流是一个PDF流对象,其数据由描述内容的一系列指令组成 要绘制在页面上的图形元素。说明应以PDF对象的形式表示, 使用与PDF文档其余部分相同的对象语法

因此,它们大多是ASCII值。文本绘图指令的字符串参数也是例外。它们的编码完全取决于绘制字符串时当前选择的字体,字体可能使用标准编码,但也可能使用完全混乱的特殊编码

PS:如果您碰巧尝试分析加密的PDF,您将发现加密
适用于文档PDF文件中的所有字符串和流,只有极少数例外。尤其是加密不适用于字典和数组结构、数字和名称。因此,没有意识到这一点的人可能不会意识到PDF是加密的,而是假设字符串和流是以一种非常奇怪的方式编码的。

补充@mkl和@davidvandriesche的优秀答案

这里有三个开源命令行工具,可以帮助您将任何PDF转换为不同的形式,以扩展/解压缩/解码对象流(请注意,没有一种“唯一正确”的方法可以做到这一点,因此每种工具的输出都是不同的):

  • 每一个都应该通过您最喜欢的操作系统包管理器提供

    pdftk
    用法示例:

    pdftk in.pdf cat output out1.pdf uncompress
    
    mutool clean -d in.pdf out2.pdf
    
    qpdf --qdf --object-streams=disable in.pdf out3.pdf
    
    mutool
    示例用法:

    pdftk in.pdf cat output out1.pdf uncompress
    
    mutool clean -d in.pdf out2.pdf
    
    qpdf --qdf --object-streams=disable in.pdf out3.pdf
    
    qpdf
    示例用法(我最喜欢的工具):

    pdftk in.pdf cat output out1.pdf uncompress
    
    mutool clean -d in.pdf out2.pdf
    
    qpdf --qdf --object-streams=disable in.pdf out3.pdf
    

    您应该尝试每一种方法,比较不同输入PDF的输出,然后确定哪一种是您最喜欢的(但当您遇到您最喜欢的显示意外结果的情况时,千万不要忘记记住其他工具)。

    答案是否回答了您所有的问题?还是有什么悬而未决的问题?