2017-04-18 68 views
-2

由于cups-PDF创建的PDF文档中的字符映射为奇怪的符号[在Ubuntu Linux 14.04和16.04上},我确实遇到了问题。即使Python告诉我它的字符串类型,我认为它是某种unicode。 type(object) python返回"string"将PDF格式的字符重新映射为可读文本

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

当我通过例如从这样创建的PDF文件复制文本的名称为“拉斐尔”变成"✡✍✑✒✍☛✓"所以每个单个字符映射到"✡=R ✍=a ✑=p ✒=h ✍=a ☛=e ✓=l"

另一个例子是:"Devel"变成"✭☛✮☛✓"

我怎样才能用Python编写一个函数,将这个“错误”的信息转移到正确的信息上?在PDF文档中,所有内容都完美可读。

这与cup-PDF使用postscript来创建PDF但不向文档中添加正确的字体/字符信息。

如果信件'l'总是符号'✓'这是本checkmark unicode character

我可怎么办字符的重映射在这个陌生的代表性纠正Python中的代表性?那么我怎样才能将符号'✓'转换或重新映射到字母'l'?任何想法?

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

+0

是的,PDF似乎是使用专门的字体,以防止复制。文本是* scrambled *,但字体中的字母也是如此。因此,如果'a'曾经被映射到Unicode代码点U + 0061,那么PDF已经用U + 270D替换了所有这些a,而特殊字体用字母a代替了正常的“WRITING HAND”字形。这是一个替代密码。 –

+0

你是对的Martijn彼得斯等于unicode“U + 270D”,我怎么解密文本?我如何将这些字母映射回原始值?现在是“U + 270D”回到“U + 0061”?是否有任何Python函数? –

回答

0

该PDF似乎使用专用字体来防止复制。文本是乱码,但字体中的字母也是如此。因此,如果a曾经被映射到Unicode代码点U + 0061,PDF已经用U + 270D代替了所有这些a,而特殊字体用字母a代替了正常的“WRITING HAND”字形。

换句话说,它使用的是substitution cypher

您必须像解密密钥一样对其进行解密:您需要创建一个从加密代码点到未加密代码点的反向映射。您可以使用PDF作为指导;作为一个人,您可以轻松阅读实际的文本,并且还可以看到它与复制的Unicode代码点之间的关系。

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

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

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

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

一旦你有了一张表,Python就可以为你做翻译;我已经采取了你的线索,并创造了只是这些信件的部分表:

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

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

print(encrypted.translate(mapping)) 

所有你需要做的就是填写其余映射; str.translate() method然后会照顾其余的。

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

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

伟大和详细的说明。也许我现在可以在星期六参加我的婚礼。没有你的帮助,我无法及时做到这一点。 - 非常感谢你 - 我会用Python2.7来试试这个,并很快回复! –

+0

@MisterWong:确保你使用'unicode'字符串; 'str.translate()'和'unicode.translate()'方法在签名上有所不同。上面的代码适用于Python 3和Python 2'unicode.translate()'。 –