PyPDF2 - PDF编码问题

时间:2013-10-14 23:49:18

标签: python encoding

我正在尝试使用PyPDF2在Python 3.3.2下加密PDF文件。

代码非常简单:

password = 'password';
# password = password.encode('utf-8')
PDFout.encrypt(user_pwd=password,owner_pwd=password)

但是我收到以下错误,具体取决于编码是打开还是关闭:

on: TypeError: slice indices must be integers or None or have an __index__ method

off: TypeError: Can't convert 'bytes' object to str implicitly

您是否知道如何解决这个问题?

谢谢和问候 彼得

2 个答案:

答案 0 :(得分:1)

在我看来,当前版本的PyPDF2(撰写本文时为1.19)有一些与Python 3兼容的错误,这就是导致这两个错误消息的原因。 GitHub for PyPDF2的更改日志表明在版本1.16中添加了Python 3支持,该版本仅在3个半月前发布,因此可能尚未报告或修复此错误。 GitHub还显示该项目的一个分支专门用于Python 3.3支持,目前尚未合并回主分支。

这两个错误都发生在PyPDF2模块的pdf.py文件中。以下是发生的事情:

PyPDF2模块创建一些额外的字节作为填充,并将其与您的密码连接。如果Python版本小于3,则填充将创建为字符串文字。如果版本为3或更高版本,则使用“latin-1”编码对填充进行编码。在Python 3中,这意味着填充是一个字节对象,并将其与字符串对象(您的密码)连接起来会产生您看到的TypeError。在Python 2下,连接将起作用,因为两个对象都是相同的类型。

使用“utf-8”对密码进行编码时,可以解决该问题,因为在这种情况下,密码和填充都是字节对象。但是,您最终会在模块中遇到第二个错误。 pdf.py文件创建并使用变量“keylen”,如下所示:

keylen = 128 / 8
... # later on in the code...
key = md5_hash[:keylen]
分区运算符在Python 2.2中进行了更改,从Python 3开始改变了它的默认行为。简而言之,“/”表示Python 2中的分区并返回一个int,但它意味着Python 3中的真正除法并返回一个浮动。因此,“keylen”在Python 2中将为16,而在Python 3中为16.0。与int不同,Floats不能用于拼接数组,因此Python 3会抛出您在评估md5_hash [:keylen]时看到的TypeError。 Python 2可以毫无错误地运行它,因为keylen将是一个int。

你可以通过改变模块的源代码来解决第二个问题,使用“//”运算符(这意味着底层划分并在Python 2和3中返回一个int):

keylen = 128 // 8

然而,您将在代码中遇到第三个错误,也与Python 3兼容性有关。我不会通过描述来说明这一点。根据我的看法,对你的问题的简短回答是要么使用Python 2,要么修补各种代码兼容性问题,要么使用不同的Python PDF库,它更好地支持Python 3(如果存在哪个符合您的特殊要求。)

答案 1 :(得分:0)

尝试安装最新版本的 PyPDF2 - 它现在完全支持Python 3!

似乎"一些"支持在1.16中添加,但它没有涵盖所有功能。现在,Py 3应该与这个库完全兼容。

相关问题