本文以Deepin Linux系统为平台,解密PDF文档。它只能是解除PDF文件的所有者权限的密码,如果是用户密码则解不了,即只能解除你能打开但编辑和复制需要密码的PDF文件,那种打开就要密码的解不了,除非暴力破解。相关可参考Linux下使用pdfcrack破解PDF密码。以下是详细的方法。
原理 设置了所有者权限的PDF文件的内容实质上并未加密,使用pikepdf读取置了所有者权限的PDF文件,并将读取的内容保存为新的PDF文件即可解除加密,可以愉快的编辑和复制文档内容了。
警告 解密PDF文档前请确定你有权编辑及移除这个文件的密码。
准备工作 pip3安装命令: sudo apt-get install python3-pip pikepdf模块安装命令: pip3 install pikepdf
程序说明 GUI框架:Tkinter PDF读写模块:pikepdf 程序逻辑: 选择目标文件夹选择,既要修改的PDF文档所在的文件夹。 选择输出文件夹,既文件解密完成后放去哪个文件夹。 点击“解密”按钮,程序会读取目标文件夹的文件列表,选择pdf文件进行解密,并保存到输出文件夹。 解密过程中会不断更新 statusLable 标签的内容说明解密到第几个文件。
程序源码 from tkinter import * from tkinter.filedialog import * import threading import pikepdf import os def __selectInputPath(): inputPath=askdirectory(parent=root, mustexist=True) inputEntry.delete(0, END) inputEntry.insert(0, inputPath) def selectInputPath(): T=threading.Thread(target=__selectInputPath()) T.start() def __selectOutputPath(): outputPath=askdirectory() outputEntry.delete(0, END) outputEntry.insert(0, outputPath) def selectOutputPath(): T=threading.Thread(target=__selectOutputPath()) T.start() def __jiemi(): inFile = inputPath.get() outFile = outputPath.get() filelist = os.listdir(inFile) count=0 k=len(filelist) for file in filelist: if file.endswith(".pdf")and ("~$" not in file):#当文件为pdf文件且不是临时文件 filePath = inFile + "/"+ file tips="正在转换第"+str(count+1)+"个文件" statusLable.config(text = tips) statusLable.update() with pikepdf.open(filePath) as pdf: num_pages = len(pdf.pages) del pdf.pages[-1] pdf.save(outFile + "/"+ file) count+=1 statusLable.config(text = "已完成") statusLable.update() def jiemi(): T=threading.Thread(target=__jiemi()) T.start() if __name__ == "__main__": root = Tk() root.title("PDF解密工具") inputPath = StringVar() outputPath = StringVar() # 获取显示区域的宽度和高度 screenWidth = root.winfo_screenwidth() screenHeight = root.winfo_screenheight() #设置窗口大小 width = 358 # 设定窗口宽度 height = 120 # 设定窗口高度 left = (screenWidth - width) / 2 top = (screenHeight - height) / 2 root.geometry("%dx%d+%d+%d" % (width, height, left, top)) #禁止用户调整窗口大小 root.resizable(False,False) inputLabel=Label(root,text = "目标路径:") inputLabel.grid(row = 0, column = 0) inputEntry=Entry(root, textvariable = inputPath) inputEntry.grid(row = 0, column = 1) inputButton=Button(root, text = "路径选择", command = selectInputPath) inputButton.grid(row = 0, column = 2) outputLabel=Label(root,text = "输出路径:") outputLabel.grid(row = 1, column = 0) outputEntry=Entry(root, textvariable = outputPath) outputEntry.grid(row = 1, column = 1) outputButton=Button(root, text = "路径选择", command = selectOutputPath) outputButton.grid(row = 1, column = 2) jiemiButton=Button(root, text = "解密", command = jiemi) jiemiButton.grid(row = 2, column = 2) statusLable=Label(root,text = "空闲中") statusLable.grid(row = 2, column = 0, columnspan=2) root.mainloop()
写在最后 Q:为什么不打包好一个deb? A:我也想打包,可以能力不够。我用Pyinstaller打包成二进制文件的时候都出问题了。打包过程没问题不过程序运行的时候,显示找不到pikepdf模块,整了很长时间,并且各种方法试过了,还是搞不定。所以只能直接用源码运行了,不过在Windows平台好像没这问题。
Q:为什么文件选择器这么丑?而且这么难用? A:因为用的是Tkinter框架,所以用的也是Tkinter内置的文件选择器。我本来想尝试通过调用深度文件管理器的文件选择器来获取路径的。可是查了半天找不到法子,我也很无奈。 Q:为什么程序容易出问题? A:没写异常处理。 Q:我尝试用pyinstaller打包为什么文件这么大? A:因为把太多没用的东西打包进来了,建立个专用的虚拟环境就好了。 Pipenv安装与使用可以参考以下截图:
安装pipenv: pip3 install pipenv 使用pipenv创建一个虚拟环境(3.7是我Python版本,你可以换成你自己的): pipenv --python 3.7 安装pikepdf模块: pip install pikepdf 安装pyinstaller模块: pip install pyinstaller PyInstaller各参数含义可以参考以下截图:
进入源代码的py文件所在目录: cd /xxx/xxx/xxx/xxx 使用pyinstaller进行打包: pyinstaller -D FuckPDFRestrict.py 进入到/xxx/xxx/xxx/xxx/dist/FuckPDFRestrict目录,找到FuckPDFRestrict文件执行即可。 建议在终端执行,可以看到报错信息: ./xxx/xxx/xxx/xxx/dist/FuckPDFRestrict/FuckPDFRestrict
相关主题 |