python 7z带特殊字符的密码

2024-10-01 09:42:22 发布

您现在位置:Python中文网/ 问答频道 /正文

我正试图解压一个带有7z.exe的文件,密码中包含特殊字符

例如&)kra932(lk0¤23

通过执行以下命令:

subprocess.call(['7z.exe', 'x', '-y', '-ps^&)kratsaslkd932(lkasdf930¤23', 'file.zip'])

7z.exe启动正常,但它显示密码错误。在

这是我创建的一个文件,它让我发疯了。在

如果我在windows命令行上运行这个命令,它运行得很好

^{pr2}$

如何使python转义&字符?在


@Wim密码出现问题,因为当我执行

7z.exe x -y -ps^&)kratsaslkd932(lkasdf930¤23 file.zip 

它显示无效命令')kratsaslkd932(lkasdf930¤23' 我使用的是python2.76,由于公司工具只能在2.76上运行,所以不能升级到3.x


Tags: 文件命令密码zipcallexefileps
3条回答

我建议使用一个原始字符串和shlex模块(特别是在Windows上),不支持除ASCII之外的任何编码。在

import shlex
import subprocess

cmd = r'7z.exe x -y -p^&moreASCIIpasswordchars file.zip'
subprocess.call(shlex.split(cmd))

回到非ASCII字符问题。。。在

我很确定在Python版本<;3中,您不能使用非ASCII字符。我不是C专家,但是请注意2.7和{a2}之间的区别。前者使用“标准”字符,而后者使用宽字符。在

请尝试在密码之间加上双引号,否则cmd解析器将按原样解析特殊字符,而不是将其作为密码的一部分。在

例如, 7z.exe x -y -ps^&)kratsaslkd932(lkasdf930¤23 file.zip不起作用。在

但是7z.exe x -y -p"s^&)kratsaslkd932(lkasdf930¤23" file.zip肯定能起作用。在

在命令行上传递密码存在很大的安全风险。通过管理权限,可以检索该信息(startup info对象)并提取密码。更好的解决方案是将7zip作为一个进程打开,并将密码输入到其标准输入中。在

下面是一个命令行压缩“源.txt“进入”dest.7z“:

CMD = ['c:\\Program Files\\7-Zip\\7z.exe', 'a', '-t7z', '-p', 'c:\\source.txt', 'd:\\dest.7z']
PASSWORD = "Nj@8G86Tuj#a"

首先需要将密码转换为输入字符串。请注意,7-zip要求在终端中输入密码。您可以使用特殊字符,只要它们可以在终端中表示。终端的编码很重要!例如,在匈牙利语窗口中,您可能希望使用“cp1250”编码。在所有情况下,标准输入都是二进制文件,它需要一个二进制字符串(python3中的“bytes”)。如果您希望安全起见,您可以将密码限制为纯ascii,并按如下方式创建输入:

^{pr2}$

如果您知道终端的编码,那么您可以将密码转换为该编码。您还可以检测密码是否不能与系统编码一起使用。(顺便说一句,这也意味着它也不能交互使用。)

(上次检查时,Windows上的不同区域设置的终端编码是不同的。也许有个窍门可以把它改成UTF-8,但我不知道怎么改。)

以下是执行命令的方式:

import subprocess
import typing

def execute(cmd : typing.List[str], input: typing.Optional[bytes] = None, verbose=False, debug=False, normal_priority=False):
    if verbose:
        print(cmd)
    creationflags = subprocess.CREATE_NO_WINDOW
    if normal_priority:
        creationflags |= subprocess.NORMAL_PRIORITY_CLASS
    else:
        creationflags |= subprocess.BELOW_NORMAL_PRIORITY_CLASS

    if debug:
        process = subprocess.Popen(cmd, shell=False, stdout=sys.stdout, stderr=sys.stderr, stdin=subprocess.PIPE,
                                   creationflags=creationflags)
    else:
        process = subprocess.Popen(cmd, shell=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
                                   stdin=subprocess.PIPE, creationflags=creationflags)
    if input:
        process.stdin.write(input)
        process.stdin.flush()
    returncode = process.wait()
    if returncode:
        raise OSError(returncode)


CMD = ['c:\\Program Files\\7-Zip\\7z.exe', 'a', '-t7z', '-p', 'c:\\source.txt', 'd:\\dest.7z']
PASSWORD = "Nj@8G86Tuj#a"
input = (PASSWORD + "\r\n").encode("ascii")
execute(CMD, input)

这也展示了如何降低进程优先级(在压缩大量数据时,这通常是一个好主意),还展示了如何将标准输出和标准错误转发到控制台。在

绝对正确的解决方案是加载7-zip DLL并使用其API。(我没有检查,但可能会使用8位二进制字符串作为密码。)

注意:本例适用于Python3,但Python2也同样适用。在

相关问题 更多 >