【问题标题】:python 7z password with special characters带有特殊字符的python 7z密码
【发布时间】:2014-03-03 21:29:41
【问题描述】:

我正在尝试使用7z.exe 解压缩文件,并且密码中包含特殊字符

前。 &)kra932(lk0¤23

通过执行以下命令:

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

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

这是我创建的文件,它让我发疯。

如果我在 windows 命令行上运行命令,它运行良好

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

如何让 python 转义 & 字符?


@Wim 问题发生在密码上,因为当我执行时

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

它说无效命令')kratsaslkd932(lkasdf930¤23' 我使用 python 2.76,由于公司工具只能在 2.76 上运行,因此无法升级到 3.x

【问题讨论】:

  • 听起来像 Python 2.7!如果是这样:subprocess.call(['7z.exe', 'x', '-y', u'-ps^&)kratsaslkd932(lkasdf930¤23', 'file.zip'])
  • 您的密码从哪个字符开始?示例密码与您实际使用的密码不同。
  • 什么版本的 Python?什么样的特殊字符,例如非字母数字、unicode、bash 转义字符?我在你的例子中看到了所有三个。
  • 顺便说一句,我认为您的问题是 ¤ 字符,而不是 &。上面的 Kroltans 建议可能会奏效!
  • 如果在 python3 上运行是一个选项,您的代码原样也可以工作。

标签: python unzip 7zip


【解决方案1】:

我建议使用原始字符串和 shlex 模块(尤其是在 Windows 上)并且不支持除 ASCII 以外的任何编码。

import shlex
import subprocess

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

回到非ASCII字符问题...

我很确定在 Python 版本 2.7 和 3.3 之间的区别。前者使用“标准”字符,而后者使用宽字符。

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    【解决方案3】:

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

    下面是一个将“source.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 需要在终端中输入密码。您可以使用特殊字符,只要它们可以在您的终端中表示即可。终端的编码很重要!例如,在匈牙利语 Windows 上,您可能希望使用“cp1250”编码。在所有情况下,标准输入都是二进制文件,它需要一个二进制字符串(Python 3 中的“字节”)。如果您想安全起见,可以将密码限制为纯 ascii 并创建如下输入:

    input = (PASSWORD + "\r\n").encode("ascii")
    

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

    (上次我检查时,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 位二进制字符串作为密码。)

    注意:此示例适用于 Python 3,但同样适用于 Python 2。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-05
      • 2021-10-12
      • 1970-01-01
      • 1970-01-01
      • 2022-01-02
      • 1970-01-01
      • 1970-01-01
      • 2020-02-07
      相关资源
      最近更新 更多