将乱序的 PDF 字符重新映射为可读文本

remap scrambled PDF characters to readable text

我确实遇到了一个问题,因为 cups-PDF 创建的 PDF 文档中的字符被映射到奇怪的符号 [在 Ubuntu Linux 14.04 和 16.04 上}。我认为它是某种 unicode,即使 Python 告诉我它的字符串类型。 type(object) python returns "string"

如果我通过 evince/Firefox 的鼠标复制粘贴或通过 Python PDFminer 模块从 PDF 中抓取文本,没有区别。所以它是真的,PDF 有损坏的文本信息,这些信息在 PDF 文档本身上是正确的。我不知道,但 PDF 文档上的文本和文本图形似乎没有紧密结合在一起。

当我通过示例从此类创建的 PDF 文档中复制文本时,名称 "Raphael" 变成 "✡✍✑✒✍☛✓" 因此每个字符都映射到 "✡=R ✍=a ✑=p ✒=h ✍=a ☛=e ✓=l"

又如:"Devel"变为"✭☛✮☛✓"

如何在 Python 中编写一个函数,将 "wrong" 信息转换为正确的信息?在 PDF 文档上,所有内容都非常可读。

这与使用 postscript 创建 PDF 但未向文档添加正确的 font/character 信息的 cups-PDF 有关。

如果字母 'l' 总是符号 '✓' 就是这个 checkmark unicode character

如何重新映射这种奇怪表示形式中的字符以更正 Python 中的表示形式?那么如何将符号 '✓' 移动或重新映射为字母 'l'?有什么想法吗?

为什么我需要这个? 我需要在此文档中搜索文本值。

PDF 似乎使用了专门的字体来防止复制。文本是 乱码,但字体中的字母也是如此。因此,如果 a 曾经被映射到 Unicode 代码点 U+0061,则 PDF 将所有那些 a 替换为 U+270D,并且特殊字体将正常的 "WRITING HAND" 字形替换为字母 a。

换句话说,它使用了 substitution cypher

您必须像任何其他替换密码一样对其进行解密:您需要创建从加密代码点到未加密代码点的反向映射。您可以使用 PDF 作为指南;作为人类,您可以轻松阅读实际文本,还可以查看它与复制的 Unicode 代码点的关系。

比如我们知道U+270D映射到U+0061:

>>> hex(ord('✍'))
'0x270d'
>>> hex(ord('a'))
'0x61'

因为当您从 PDF 复制 a 时,您得到的是 270d 代码点。只需为字母表的其余部分构建一个 table。这听起来像是很多手工工作,但您已经有了明文。想象一下不知道文本包含什么(例如,您只有复制文本产生的符号);那么你必须先做一个完整的密码分析(对于替换密码,假设一种特定的语言,并计算符号;每种语言都有一个典型的字母频率分布,这种分布通常可以在加密的文本正文中匹配映射回原始字母)。

理论上,您应该能够提取专用字体,然后对其进行分析以生成翻译 table。然而,这需要某种形式的计算机视觉;计算机不会轻易知道像素栅格或矢量线系列形成特定字母。对于大约 70 个代码点(大写、小写、数字、一些标点符号),手动创建 table 可能会更容易。

一旦您有了 table,Python 可以为您翻译;我已经根据你的线索为这些字母创建了部分 table:

mapping = {
    0x270d: 'a',
    0x261b: 'e',
    0x2712: 'h',
    0x2713: 'l',
    0x2711: 'p',
    0x272e: 'v',

    0x272d: 'D',
    0x2721: 'R',
}

print(encrypted.translate(mapping))

您需要做的就是填写剩余的映射; str.translate() method 会处理剩下的事情。

在您的样本加密文本样本上使用上述部分 table 的演示:

>>> print("✡✍✑✒✍☛✓".translate(mapping))
Raphael
>>> print("✭☛✮☛✓".translate(mapping))
Devel