简体   繁体   English

带有特殊字符的python 7z密码

[英]python 7z password with special characters

I'm trying to unzip a file with 7z.exe and the password contains special characters on it 我正在尝试用7z.exe解压缩文件,密码中包含特殊字符

EX. EX。 &)kra932(lk0¤23

By executing the following command: 通过执行以下命令:

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

7z.exe launches fine but it says the password is wrong. 7z.exe启动正常,但它说密码错误。

This is a file I created and it is driving me nuts. 这是我创建的文件,它让我疯狂。

If I run the command on the windows command line it runs fine 如果我在Windows命令行上运行命令它运行正常

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

How can I make python escape the & character? 如何让python转义&字符?


@Wim the issue occurs & on the password, because when i execute @Wim问题发生在密码上,因为当我执行时

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

it says invalid command ')kratsaslkd932(lkasdf930¤23' im using python 2.76, cant upgrade to 3.x due to company tools that only run on 2.76 它说无效命令')kratsaslkd932(lkasdf930¤23'即时使用python 2.76,由于公司工具只能在2.76运行,因此无法升级到3.x

I'd suggest using a raw string and the shlex module (esp. on Windows) and NOT supporting any encoding other than ASCII. 我建议使用原始字符串和shlex模块(特别是在Windows上),不支持ASCII以外的任何编码。

import shlex
import subprocess

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

Back to the non-ASCII character issue... 回到非ASCII字符问题......

I'm pretty sure in Python versions < 3 you simply can't use non-ASCII characters. 我很确定在Python版本<3中你根本不能使用非ASCII字符。 I'm no C expert, but notice the difference between 2.7 and 3.3 . 我不是C专家,但注意2.73.3之间的区别。 The former uses a "standard" char while the later uses a wide char. 前者使用“标准”字符,而后者使用宽字符。

Try to put double quotes between your password, otherwise the cmd parser would any parse special character as is instead of taking it as part of the password. 尝试在密码之间加上双引号,否则cmd解析器将按原样解析特殊字符,而不是将其作为密码的一部分。

For example, 7z.exe x -y -ps^&)kratsaslkd932(lkasdf930¤23 file.zip won't work. 例如, 7z.exe x -y -ps^&)kratsaslkd932(lkasdf930¤23 file.zip将无效。

But 7z.exe x -y -p"s^&)kratsaslkd932(lkasdf930¤23" file.zip would definitely work. 7z.exe x -y -p"s^&)kratsaslkd932(lkasdf930¤23" file.zip肯定会有效。

There is a big security risk in passing the password on the command line. 在命令行上传递密码存在很大的安全风险。 With administrative rights, it is possible to retrieve that information (startup info object) and extract the password. 使用管理权限,可以检索该信息(启动信息对象)并提取密码。 A better solution is to open 7zip as a process, and feed the password into its standard input. 更好的解决方案是打开7zip作为进程,并将密码提供给其标准输入。

Here is an example of a command line that compresses "source.txt" into "dest.7z": 以下是将“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"

First you need to convert the password into an input string. 首先,您需要将密码转换为输入字符串。 Please note that 7-zip expects the password to by typed into the terminal. 请注意,7-zip需要输入密码到终端。 You can use special characters as long as they can be represented in your terminal. 您可以使用特殊字符,只要它们可以在您的终端中表示即可。 The encoding of the terminal matters! 终端的编码很重要! For example, on Hungarian Windows, you might want to use "cp1250" encoding. 例如,在匈牙利语Windows上,您可能希望使用“cp1250”编码。 In all cases, the standard input is a binary file, and it expects a binary string ("bytes" in Python 3). 在所有情况下,标准输入都是二进制文件,它需要二进制字符串(Python 3中的“字节”)。 If you want to be on the safe side, you can restrict passwords to plain ascii and create your input like this: 如果您想要安全起见,可以将密码限制为plain ascii并创建输入,如下所示:

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

If you know the encoding of your terminal, then you can convert the password to that encoding. 如果您知道终端的编码,则可以将密码转换为该编码。 You will also be able to detect if the password cannot be used with the system's encoding. 您还可以检测密码是否不能与系统的编码一起使用。 (And by the way, it also means that it cannot be used interactively either.) (顺便说一下,它也意味着它也不能以交互方式使用。)

(Last time I checked, the terminal encoding was different for different regional settings on Windows. Maybe there is a trick to change that to UTF-8, but I'm not sure how.) (我上次检查时,Windows上的不同区域设置的终端编码是不同的。也许有一个技巧可以将其更改为UTF-8,但我不确定如何。)

This is how you execute a command: 这是您执行命令的方式:

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)

This also shows how to lower process priority (which is usually a good idea when compressing large amounts of data), and it also shows how to forward standard output and standard error to the console. 这还显示了如何降低进程优先级(压缩大量数据时通常是一个好主意),并且还显示了如何将标准输出和标准错误转发到控制台。

The absolute correct solution would be to load 7-zip DLL and use its API. 绝对正确的解决方案是加载7-zip DLL并使用其API。 (I did not check but that can probably use 8 bit binary strings for passwords.) (我没有检查,但可能使用8位二进制字符串作为密码。)

Note: this example is for Python 3 but the same can be done with Python 2. 注意:此示例适用于Python 3,但Python 2也可以这样做。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM