懶惰之最|GitHub 實測

電子帳單每份都要輸身分證?實測 pikepdf:60 份 PDF 0.53 秒解開,但一個壞檔就讓程式停擺

2026-10-06|專案:pikepdf/pikepdf|Markdown 版

重點摘要

  • 用 pikepdf 寫十幾行 Python,輪流試自己的身分證與生日密碼,60 份 AES-256 加密的假帳單 PDF 在 0.53 秒內全部解開,600 份約 5.08 秒。
  • pikepdf 對 RC4-40、RC4-128、AES-128、AES-256 四種 PDF 加密方式,只要密碼正確都能解開;密碼大小寫不同(小寫 a123456789)就打不開。
  • 資料夾混進一個損壞的 PDF 時,最簡單的批次腳本會因 PdfError 直接中斷,實測 60 份只解了 36 份,需要另外處理壞檔。
  • pikepdf 沒有破解功能,只能用已知密碼打開自己的檔案;它是 Python 套件,需要會執行程式。
  • 結論: 會寫一點 Python 的人,用 pikepdf 批次解開自己的加密電子帳單又快又可靠,但要自己處理壞檔,否則只會做一半。
  • 適合: 每月收大量加密電子帳單、想批次歸檔或合併,且能執行簡單 Python 腳本的人。
  • 不適合: 完全不想碰指令的人,以及想打開不知道密碼之檔案的人(它沒有破解功能)。
實測項目 結果
安裝(pip install pikepdf) 約 3 秒
60 份 AES-256 假帳單批次解密 0.51–0.53 秒,60/60 成功
600 份批次解密 5.08 秒,600/600 成功
RC4-40/RC4-128/AES-128/AES-256 密碼正確時全部解開
密碼小寫、少一碼、多一個空白 都打不開
混進 1 個損壞 PDF 腳本中斷,只解 36/60 份
解開後 60 份合併 60 頁、103KB,不到 0.1 秒
解開後內容 與加密前原檔逐位元組相同

月底想對帳,打開信箱:信用卡、電信、保險的電子帳單,每一份 PDF 都要輸入身分證字號才打得開。想翻一整年的紀錄,三張卡加電信加保險,就是 60 份、60 次輸入。

pikepdf 是 GitHub 上一個不到三千星(實測時 2,808 星)的 Python 套件,專門讀寫、修復、轉換 PDF,底層是老牌的 C++ 函式庫 qpdf。它沒有圖形介面,但只要十幾行程式,就能用「你自己知道的密碼」把整個資料夾的帳單一次解開。這篇記錄實際跑出來的結果,包括兩個會讓人卡住的地方。

測試設備: Mac mini M4 Pro(12 核、64GB),Python 3.12,pikepdf 10.16.0(內含 qpdf 12.4.2)。

全部使用假資料: 帳單是我自己用程式產生的,範例身分證字號 A123456789、範例生日 19900101,沒有用任何真實帳單或個資。

安裝:一行,約 3 秒

pip install pikepdf

有預編譯好的版本,不用另外裝系統套件,實測約 3 秒裝好。

準備 60 份加密的假帳單

我做了一年份的假帳單:三張信用卡各 12 份、電信 12 份、保險 12 份,共 60 份。信用卡與電信用身分證當密碼,保險用生日當密碼,加密方式是 AES-256。不給密碼直接開,pikepdf 會丟出 PasswordError: invalid password。

核心腳本:輪流試自己的密碼

import pikepdf, glob, os, time
mine = ['A123456789', '19900101']  # 自己的密碼
os.makedirs('unlocked', exist_ok=True)
t, ok = time.time(), 0
for f in sorted(glob.glob('bills/*.pdf')):
  for pw in mine:
    try:
      with pikepdf.open(f, password=pw) as p:
        p.save(f.replace('bills', 'unlocked'))
        ok += 1; break
    except pikepdf.PasswordError:
      pass
print(f'解開 {ok} 份,{time.time()-t:.2f} 秒')

邏輯很單純:每份帳單把你的密碼清單從頭試一遍,打得開就另存一份到 unlocked 資料夾。原始檔不會被改動。

60 份帳單 0.53 秒全部解開

python3 unlock.py
# 解開 60 份,0.53 秒

我另外比對過:解開後的檔案不再需要密碼,頁面內容和加密前的原檔逐位元組相同。

實測數字

項目 結果
安裝(pip) 約 3 秒
60 份 AES-256 帳單解開 0.51–0.53 秒,60/60 成功
放大到 600 份 5.08 秒,600/600 成功
加密方式 RC4-40、RC4-128、AES-128、AES-256 四種都解得開
密碼打成小寫 a123456789 打不開
密碼少一碼、多一個空白 都打不開
混進 1 個壞檔 程式中斷,60 份只解了 36 份
60 份合併成一份 60 頁、103KB,不到 0.1 秒

踩雷一:大小寫要完全一樣

台灣的帳單密碼常是身分證字號,開頭是英文字母。我分別試了 a123456789 和 A123456789:小寫直接回報密碼錯誤,大寫才打得開。多打一個空白也一樣打不開。寫密碼清單時要照帳單通知上寫的格式,一個字都不能差。

踩雷二:一個壞檔,整批停下來

這是實測裡最痛的一點。我在資料夾裡放了一個「下載失敗」的假 PDF(其實是一段 HTML),再跑一次同樣的腳本:

混進壞檔後程式直接中斷

python3 unlock.py 2>&1 | tail -1
# pikepdf._core.PdfError: bills/broken.pdf: unable to find trailer dictionary while recovering damaged file

程式照檔名順序處理,碰到壞檔就整個中斷:60 份只解了排在它前面的 36 份,後面 24 份完全沒處理,而且沒有任何「完成幾份」的訊息。從信箱批次下載帳單時,偶爾有一份沒下載完整很常見,所以實際使用建議在 except pikepdf.PasswordError 後面再接住 pikepdf.PdfError,印出壞檔名稱後跳過(這個改法我沒有在本次實測中重跑,請自行確認)。

解開之後:合併成一份全年帳單

import pikepdf, glob
year = pikepdf.new()
for f in sorted(glob.glob('unlocked/*.pdf')):
  year.pages.extend(pikepdf.open(f).pages)
year.save('2026全年帳單.pdf')

60 份合併成一份 60 頁、103KB 的 PDF,不到 0.1 秒。要找某個月的扣款,開一個檔就能翻完。

怎麼判讀結果

我的結論

我會留著它。一年整理一次帳單、或要把一疊加密 PDF 交給會計,十幾行程式就省下幾十次輸入,速度也完全不是問題。但它是 Python 套件,不是點兩下就能用的 App:至少要會執行一個 .py 檔,壞檔也要自己處理,否則它會安靜地只做一半。

它沒有破解功能,只能用你已經知道的密碼打開你自己的檔案;忘記密碼的檔案,它一樣打不開。

適合: 每個月收一堆加密電子帳單、想批次整理或歸檔的人;會一點 Python,或願意照著範例改密碼清單的人。

不適合: 完全不想碰指令的人;想打開不知道密碼的檔案的人(它做不到,也不該這樣用)。

專案資訊

測試設備:Mac mini M4 Pro(12 核、64GB)。內容依實際執行結果撰寫,數據為撰寫當時的實測值。

← 所有實測