小智 7
你(就像我一样)一定想过 - WTF 来自"-3904"
凯文的回答。
请让自己舒服 - 我有答案)。
\n我在 PDF 1.6 参考中找到了它。您可以在这里获取: https: //www.adobe.com/content/dam/acom/en/devnet/pdf/pdf_reference_archive/PDFReference16.pdf
\n3.5节,第99页:
\n\n\n32 位整数,包含一组标志,指定使用用户访问权限打开文档时应授予的访问权限。表 3.20 显示了这些标志的含义。标志字内的位 posi\xc2\xadtions\n 编号为 1(低位)到 32\n(高位)。任何位置的 1 位都会启用相应的访问权限。哪些位有意义,以及在某些情况下如何解释它们,取决于安全处理程序\xe2\x80\x99s 修订号\n(在加密字典\xe2\x80\x99s R 条目中指定)。
\n*注意:PDF 整数对象在内部以带符号的二进制补码形式表示。由于要求加密字典\xe2\x80\x99s P val\xc2\xad ue中所有保留的高位标志位都为1,因此该值必须指定为负整数。例如,假设安全处理程序的修订版为 2,则值 -44 允许打印和复制,但不允许修改内容和注释。
\n
所以,P
就是许可!请检查该文件中的表格。-44
是以11010100
位表示的。
我是这样写的(允许打印和复制,但不允许修改内容和注释):
\nfrom hashlib import md5\n\nfrom PyPDF4 import PdfFileReader, PdfFileWriter\nfrom PyPDF4.generic import NameObject, DictionaryObject, ArrayObject, \\\n NumberObject, ByteStringObject\nfrom PyPDF4.pdf import _alg33, _alg34, _alg35\nfrom PyPDF4.utils import b_\n\n\ndef encrypt(writer_obj: PdfFileWriter, user_pwd, owner_pwd=None, use_128bit=True):\n """\n Encrypt this PDF file with the PDF Standard encryption handler.\n\n :param str user_pwd: The "user password", which allows for opening\n and reading the PDF file with the restrictions provided.\n :param str owner_pwd: The "owner password", which allows for\n opening the PDF files without any restrictions. By default,\n the owner password is the same as the user password.\n :param bool use_128bit: flag as to whether to use 128bit\n encryption. When false, 40bit encryption will be used. By default,\n this flag is on.\n """\n import time, random\n if owner_pwd == None:\n owner_pwd = user_pwd\n if use_128bit:\n V = 2\n rev = 3\n keylen = int(128 / 8)\n else:\n V = 1\n rev = 2\n keylen = int(40 / 8)\n # permit copy and printing only:\n P = -44\n O = ByteStringObject(_alg33(owner_pwd, user_pwd, rev, keylen))\n ID_1 = ByteStringObject(md5(b_(repr(time.time()))).digest())\n ID_2 = ByteStringObject(md5(b_(repr(random.random()))).digest())\n writer_obj._ID = ArrayObject((ID_1, ID_2))\n if rev == 2:\n U, key = _alg34(user_pwd, O, P, ID_1)\n else:\n assert rev == 3\n U, key = _alg35(user_pwd, rev, keylen, O, P, ID_1, False)\n encrypt = DictionaryObject()\n encrypt[NameObject("/Filter")] = NameObject("/Standard")\n encrypt[NameObject("/V")] = NumberObject(V)\n if V == 2:\n encrypt[NameObject("/Length")] = NumberObject(keylen * 8)\n encrypt[NameObject("/R")] = NumberObject(rev)\n encrypt[NameObject("/O")] = ByteStringObject(O)\n encrypt[NameObject("/U")] = ByteStringObject(U)\n encrypt[NameObject("/P")] = NumberObject(P)\n writer_obj._encrypt = writer_obj._addObject(encrypt)\n writer_obj._encrypt_key = key\n\n\nunmeta = PdfFileReader(\'my_pdf.pdf\')\n\nwriter = PdfFileWriter()\nwriter.appendPagesFromReader(unmeta)\nencrypt(writer, \'1\', \'123\')\n\nwith open(\'my_pdf_encrypted.pdf\', \'wb\') as fp:\n writer.write(fp)\n
Run Code Online (Sandbox Code Playgroud)\n如果您喜欢我的回答,请投票;)。
\n 归档时间: |
|
查看次数: |
8604 次 |
最近记录: |