流编码可以根据文档版本而变化吗?

问题描述 投票:0回答:1

您好 StackOverflow 社区,我有一个关于 PDF 文件中的 Streams 的非常有趣的问题,我有 5 个 pdf..

当我解码 pdf 页面内容流 时,我将它们按文本块分割,然后我想将它们转换为常规字符串。 (我没有从 PDF 中获取文本的任务,该任务要求我解析此数据流并从中获取文本。)

这就是我得到的:

1 个文档 文本:西里尔字母

b'BT 11 0 0 11 0 0 Tm\n/TT2 1 Tf (!"#$%&\'\\(\\)*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_
ab) Tj ET'`

2 文档 文本:这是一个小型演示 .pdf 文件 -

b'BT\r\n/F1 0010 Tf\r\n69.2500 688.6080 Td\r\n( This is a small demonstration .pdf file - ) Tj\r\nET'

3 个文件 文本:该系列中的剂量总数

b'BT 2.400000 213.686918 Td [(\x00o\x00v\x00e\x00r\x00a\x00l\x00l\x00 \x00n\x00u\x00m\x00b\x00e\x00r\x00 \x00o\x00f\x00 \x00d\x00o\x00s\x00e\x00s\x00 \x00i\x00n\x00 \x00t\x00h\x00e\x00 \x00s\x00e\x00r\x00i\x00e\x00s)] TJ ET'

4 文件 文本:出生日期(罗马尼亚语、俄语和英语)

b'BT 27.111811 391.343714 Td [(\x00D\x00a\x00t\x00a\x00 \x00n\x00a\x02\x19\x00t\x00e\x00r\x00e\x00 \x00|\x00 \x04\x14\x040\x04B\x040\x00 \x04@\x04>\x046\x044\x045\x04=\x048\x04O\x00 \x00|\x00 \x00D\x00a\x00t\x00e\x00 \x00o\x00f\x00 \x00b\x00i\x00r\x00t\x00h\x00:)] TJ ET'

5 个文档 文本:示例文本

b'BT\n0 Tr\n/F1 79.848503 Tf\n1 0 0.000000 -1 196.000000 874.080017 Tm\n[<0028>-0.839844<005B><0044>-0.847656<0050>-0.832031<0053><004F>-0.832031<0048>-0.847656<0003><0057>-0.832031<0048>-0.847656<005B><0057>-0.832031] TJ\nET'

我知道如何阅读前2个文档,但我不知道解码方法。

我知道如何阅读 3-4 个文档,因为我知道它使用 unicode 字符。(但我提到它不适用于西里尔字母).

我不知道如何使用第五个文档,而且我不明白如何解码这种类型的编码..

我欢迎任何答案、任何解释和任何建议。

谢谢你。

pdf text decode encode
1个回答
0
投票

我将使用您的挑战者示例 5 来展示 PDF 字体查找可用于理清某些编码的基本方法,这是一个相对简单且常见的组合。

您的第 5 个示例文本是非常常见的 CIDFont+F1 编码,删除字距调整,我们看到开始

[<0028>-0.839844<005B><0044>

产生
[<0028><005B><0044><0050><0053><004F><0048><0003><0057><0048><005B><0057>]

这是该编码文本的一个非常常见的映射忽略第一个条目,因为这是另一个没有该二进制字符串<0028>子集的文件(在本例中缺失)。

使用这个通用查找表,我们可以使用 ansi 字节进行转换

stream
/CIDInit /ProcSet findresource begin 12 dict begin begincmap /CIDSystemInfo << /Registry (Adobe) /Ordering (UCS) /Supplement 0 >> def /CMapName /Adobe-Identity-UCS def /CMapType 2 def 1 begincodespacerange <0000> <FFFF> endcodespacerange 33 beginbfchar <0003> <0020> <000F> <002C> <0011> <002E> <0013> <0030> <0014> <0031> <0015> <0032> <0016> <0033> <0017> <0034> <0018> <0035> <0019> <0036> <001A> <0037> <001B> <0038> <001C> <0039> <0020> <003D> <0037> <0054> <003B> <0058> <0044> <0061> <0045> <0062> <0047> <0064> <0048> <0065> <004A> <0067> <004B> <0068> <004C> <0069> <004F> <006C> <0050> <006D> <0051> <006E> <0052> <006F> <0053> <0070> <0055> <0072> <0056> <0073> <0057> <0074> <0059> <0076> <005B> <0078> endbfchar endcmap CMapName currentdict /CMap defineresource pop end end 
endstream

所以上面是成对的 Cmap,所以我们找到第一个对并转换为第二个

<005B><0078>x <0044> <0061> 一个 <0050> <006D> 米 <0053> <0070> p <004F> <006C> 我 <0048> <0065> e <0003> <0020> <0057> <0074> t <0048> <0065> e <005B> <0078> x <0057> <0074>

示例文本显然是正确的,那么什么是<0028>

从上表来看,它比

<0020> <003D>
多 8,因此应该是 <0045>

然后把我打翻在一边,这也有效(但并不总是:-)

© www.soinside.com 2019 - 2024. All rights reserved.