2013-10-14 66 views
1

我想使用PyPDF2在Python 3.3.2下加密PDF文件。PyPDF2 - 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 

你的任何機會知道怎麼解決那個問題?

感謝和問候 彼得

回答

1

這在我看來,PyPDF2的當前版本(1.19撰寫本文時)有關於使用Python 3兼容性一些錯誤,這是什麼原因造成這兩種錯誤消息。 PyPDF2的GitHub上的更改日誌表明Python 3.支持版本僅在3個半月前發佈,因此可能尚未報告或修復此bug。 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。與ints不同,float不能用於拼接數組,因此Python 3會引發評估md5_hash [:keylen]時看到的TypeError。 Python 2會運行這個沒有錯誤,因爲keylen將是一個int。

你可以通過改變模塊的源代碼以使用「//」運算解決第二個問題(這意味着地板事業部和兩個Python 2中返回一個int和3):

keylen = 128 // 8 

然而,之後你會在代碼中遇到第三個bug,也與Python 3的兼容性有關。我不會通過描述它來描述這一點。就我看來,對於你的問題的簡短回答是,要麼使用Python 2,要麼修補各種代碼兼容性問題,或者使用不同的PDF庫來獲得更好的支持Python 3的Python庫(如果存在的話滿足您的特殊要求)。

+0

謝謝基督教,這是非常有幫助! –

+0

如果你覺得它充分地回答了你的問題,你會介意將其標記爲接受的答案?謝謝! –

0

嘗試安裝最新版本的PyPDF2 - 它現在完全支持Python 3!

看來,「一些」支持1.16加入,但它並沒有涵蓋所有的功能。現在,Py 3應該與這個庫完全兼容。