PDF格式分析(三十五)Common Data Structures 通用格式结构

PDF格式中,一些通用数据结构是根据基本对象类型构建的,并且在整个PDF中的许多地方都使用。本章节会介绍文本字符串,日期,矩形,名称树和数字树的数据结构。

String Object Types 字符串对象类型

PDF 字符串对象根据具体的功能作用可以分为:文本字符串,PDFDocEncoded字符串,ASCII字符串或字节字符串。主要通过表示字符串描述的字符或字形的编码进行区分。

字符串对象类型如下表:

类型 描述
text string 应用于人工可读的文本,例如文本注释,书签名称,文章名称和文档信息。 这些字符串应使用PDFDocEncoding或带有前导字节顺序标记的UTF-16BE进行编码。
PDFDocEncoded string 用于单个字节中表示的字符和字形。
ASCII string 用于使用ASCII编码在单个字节中表示的字符。
byte string 用于表示为一系列字节的二进制数据,其中每个字节可以是以8位表示的任何值。 字符串可以表示字符,但编码是未知的。 字符串的字节可以不表示字符。 此类型应用于MD5哈希值,签名证书和Web捕获标识值等数据。

这里写图片描述

Text String Type 文本字符串

文本字符串类型应用于包含旨在人工可读的信息的字符串,例如文本注释,书签名称,文章名称,文档信息等。是字符串类型的子类型,表示使用特定约定编码的数据。

文本字符串类型编码类型可分为:PDFDocEncoding或UTF-16BE Unicode字符编码。 PDFDocEncoding可以编码所有ISO Latin 1字符集.UTF-16BE可以编码所有Unicode字符。

注:PDFDocEncoding不支持所有Unicode字符,而UTF-16BE支持。

PDFDocEncoding 字符集(PDF字符—>unicode)

    static final char pdfEncodingByteToChar[] = {
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
        16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
        32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
        48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
        64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
        80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
        96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
        112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
        0x2022, 0x2020, 0x2021, 0x2026, 0x2014, 0x2013, 0x0192, 0x2044, 0x2039, 0x203a, 0x2212, 0x2030, 0x201e, 0x201c, 0x201d, 0x2018,
        0x2019, 0x201a, 0x2122, 0xfb01, 0xfb02, 0x0141, 0x0152, 0x0160, 0x0178, 0x017d, 0x0131, 0x0142, 0x0153, 0x0161, 0x017e, 65533,
        0x20ac, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175,
        176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191,
        192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207,
        208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223,
        224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239,
        240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255};

对于用Unicode编码的文本字符串,前两个字节应为254,后跟255.这两个字节表示Unicode字节顺序标记(U + FEFF),注意:PDF格式只使用UTF-16BE(大端)编码方案编码Unicode。转义序列可以出现在Unicode文本字符串中的任何位置,以指示后续文本应写入的语言(当无法从文本中使用的字符代码确定是何种语言时,这方式很有用)。

转义序列是由下列四个部分组成的(按顺序读取):

a)Unicode值U + 001B(即字节序列0后跟27)。表示开头

b)2字节ISO 639语言代码。表示哪种语言
示例:en 表示英语,ja 表示日语编码为ASCII字符。

c)(可选)2字节ISO 3166国家/地区代码。表示地区
示例:US为美国,JP为日本。

扫描二维码关注公众号,回复: 3311386 查看本文章

d)Unicode值U + 001B。表示结尾

Byte String Type 二进制字符串

字节串类型应用于二进制数据,该二进制数据应表示为一系列字节,其中每个字节可以是以8位表示的任何值。 字节字符串类型是字符串类型的子类型。
注意:字符串可能表示字符,但编码未知。 字符串的字节可能不代表字符。

Text Streams 文本流

文本流属于PDF流对象的特例,其解密,解压缩后的字节应满足“Text String Type”的要求 ,包括:字节顺序和前导字节(U + FEFF)等。

Dates 日期

PDF中使用的日期值应符合标准日期格式,该格式严格遵循ISO / IEC 8824中定义的国际标准ASN.1(抽象语法表示法一)的格式。日期应为表格的文本字符串:(D:YYYYMMDDHHmmSSOHH’mm )
解释:
YYYY将是年份
MM应为月份(01-12)
DD应为当天(01-31)
HH应为小时(00-23)
mm 表示分钟(00-59)
SS表示秒(00-59)
O 表示当地时间与世界时(UT)的关系,也就是时差,由加号(+),减号( - )或 大写Z 表示。
HH 表示时差中的小时数(00-23),后面跟着符号(’)
mm 应为时差中的分钟数(00-59)

上面的格式中,前缀D必需存在,年份字段(YYYY)必需存在,后面字段可以不存在。MM和DD的默认值均为01; 剩余其他数字字段默认为零值。 O字段的值:加号(+)表示本地时间晚于UT,减号(-)表示本地时间早于UT,并且“Z”表示本地时间等于UT。 如果未指定UT信息,则指定时间与UT的关系应视为GMT。 无论是否指定时区,其余日期应按当地时间表示。

示例,1998年12月23日,美国太平洋标准时间下午7:52,由字符串表示:D:199812231952-08’00

Rectangles 矩形

矩形用于描述页面上的位置和各种对象的边界框。 矩形是由一个四个数字的数组表示,给出一对对角线的坐标。通常表示为:[llx lly urx ury],按顺序指定矩形的左下x,左下y,右上y和右上y坐标。

Name Trees 名称树

名称树与字典一样,也存在键和值,不过表现形式不同。 名称树在以下重要方面与字典不同:
•与字典中的键(名称对象)不同,名称树中的键是字符串。
•键是排序的。
•与键关联的值可以是任何类型的对象。 如果是流对象,应通过间接对象引用。 字典,数组和字符串对象应由间接对象引用指定,其他PDF对象(空值,数字,布尔值和名称)应指定为直接对象。
•该树形结构可以没有容量上限,可以用于高效查找。

名称树,树形结构,每个节点都应是字典对象。

下面表格显示了节点字典中的条目。 节点应为三种,具体取决于它们包含的特定条目:

1、根节点:该类型节点,有且只能有一个,该节点应包含一个条目:Kids或Names,但不能同时包含两个。 如果根节点具有Names条目,则它应该是树中的唯一节点。

1 0 obj                                    % 根节点
<< 
/Kids 
[ 
2 0 R                     
3 0 R
4 0 R
]
>>
endobj

2、中间节点:其应包含Limits条目和Kids条目

2 0 obj
<< /Limits [(Actinium) (Gold)]             % 中间节点
/Kids [ 5 0 R
6 0 R
7 0 R
8 0 R
9 0 R
10 0 R
11 0 R
]
>>
endobj
3 0 obj
<< /Limits [(Hafnium) (Protactinium)]       % 中间节点
/Kids [ 12 0 R
13 0 R
14 0 R
15 0 R
16 0 R
17 0 R
18 0 R
19 0 R
]
>>
endobj
4 0 obj
<< /Limits [(Radium) (Zirconium)]          % 中间节点
/Kids [ 20 0 R
21 0 R
22 0 R
23 0 R
24 0 R
]
>>
endob

3、叶节点:其应包含Limits条目和Names条目。

5 0 obj                                        % 叶节点
<< /Limits [(Actinium) (Astatine)]             
/Names [ (Actinium) 25 0 R
(Aluminum) 26 0 R
(Americium) 27 0 R
(Antimony) 28 0 R
(Argon) 29 0 R
(Arsenic) 30 0 R
(Astatine) 31 0 R
]
>>
endobj24 0 obj                                      % 叶节点
<< /Limits [(Xenon) (Zirconium)]             
/Names [ (Xenon) 129 0 R
(Ytterbium) 130 0 R
(Yttrium) 131 0 R
(Zinc) 132 0 R
(Zirconium) 133 0 R
]
>>
endobj
25 0 obj
89                                            % 原子序数(锕)
endobj133 0 obj
40                                            % 原子序数(锆)
endobj

大家仔细看发现,上面用名称树表示元素周期表。

表 - 名称树节点字典中的条目

key Type Value
Kids array (仅限根节点和中间节点;在中间节点中是必须的;当且仅当Names不存在时,存在于根节点中),表示该节点的直接子节点的数组。 孩子可能是中间节点或叶子节点。
Names array (仅限根节点和叶节点;叶节点中是必须的;当且仅当Kids不存在时,存在于根节点中)应为[key1 value1 key2 value2 … keyn valuen]形式的数组,其中每个keyi应为字符串,并且相对应的valuei应该是与该键相关联的对象。 key应按词汇顺序排序。
Limits array (仅限中间节点和叶节点;必需)两个字符串的数组,用来指定叶子节点或中间节点的Names数组中包含的最小和最大key(词汇顺序)

各节点名称条目中包含的key不得重复; 每个Names条目应包含树中所有键的单个连续范围。

Number Trees 数字树

数字树类似于名称树,除了它的键是整数而不是字符串,并且应按数字升序排序。 包含键值对的叶子(或根)节点中的条目应命名为Nums,而不是名称树中的Names。 下表显示了数字树节点字典中的条目:

表 - 数字树节点字典中的条目

key Type Value
Kids array (仅限根节点和中间节点;在中间节点中是必须的;当且仅当Nums不存在时,存在于根节点中),表示该节点的直接子节点的数组。 孩子可能是中间节点或叶子节点。
Nums array (仅限根节点和叶节点;叶节点中是必须的;当且仅当Kids不存在时,存在于根节点中)应为[key1 value1 key2 value2 … keyn valuen]形式的数组,其中每个keyi应为整数,并且相对应的valuei应该是与该键相关联的对象。 key应按数字升序排序。
Limits array (仅限中间节点和叶节点;必需)两个整数的数组,用来指定叶子节点或中间节点的Nums数组中包含的最小和最大key(升序)

猜你喜欢

转载自blog.csdn.net/steve_cui/article/details/82701061