diff --git a/MainWindow.py b/MainWindow.py index 1c03fea..52c5acc 100644 --- a/MainWindow.py +++ b/MainWindow.py @@ -16,11 +16,14 @@ def __init__(self, master=None): def create_variables(self): self.cryptOption = tk.StringVar() self.dataOption = tk.StringVar() + self.nameOption = tk.StringVar() # 创建控件 def create_widgets(self): self.cryptOptionCombobox = ttk.Combobox(self, width=10, textvariable=self.cryptOption) self.dataOptionCombobox = ttk.Combobox(self, width=10, textvariable=self.dataOption) + # 选择文件夹选项时是否加密解密文件名 + self.nameCryptoOptionCombobox = ttk.Combobox(self, width=10, textvariable=self.nameOption) self.populate_comboboxes() self.passwordEntry = ttk.Entry(self, width=40, show="*") self.passwordShowButton = ttk.Button(self, text="密码", width=5, command=self.password_show) @@ -44,18 +47,19 @@ def create_widgets(self): def create_layout(self): pad_w_e = dict(sticky=(tk.W, tk.E), padx="0.5m", pady="0.5m") self.passwordShowButton.grid(row=0, column=0, **pad_w_e) - self.passwordEntry.grid(row=0, column=1, columnspan=2, **pad_w_e) + self.passwordEntry.grid(row=0, column=1, columnspan=3, **pad_w_e) self.fileFromChooseButton.grid(row=1, column=0, **pad_w_e) - self.textFromEntry.grid(row=1, column=1, columnspan=2, **pad_w_e) + self.textFromEntry.grid(row=1, column=1, columnspan=3, **pad_w_e) self.fileToChooseButton.grid(row=2, column=0, **pad_w_e) - self.textToEntry.grid(row=2, column=1, columnspan=2, **pad_w_e) + self.textToEntry.grid(row=2, column=1, columnspan=3, **pad_w_e) self.cryptOptionCombobox.grid(row=3, column=0, **pad_w_e) self.dataOptionCombobox.grid(row=3, column=1, **pad_w_e) - self.button.grid(row=3, column=2, **pad_w_e) - self.progressBar.grid(row=4, column=0, columnspan=3, **pad_w_e) - self.tree.grid(row=5, column=0, columnspan=3, sticky=(tk.N, tk.S, tk.E, tk.W)) + self.nameCryptoOptionCombobox.grid(row=3, column=2, **pad_w_e) + self.button.grid(row=3, column=3, **pad_w_e) + self.progressBar.grid(row=4, column=0, columnspan=4, **pad_w_e) + self.tree.grid(row=5, column=0, columnspan=4, sticky=(tk.N, tk.S, tk.E, tk.W)) self.ysb.grid(row=5, column=4, sticky=(tk.N, tk.S)) - self.xsb.grid(row=6, column=0, columnspan=4, **pad_w_e) + self.xsb.grid(row=6, column=0, columnspan=5, **pad_w_e) self.grid(row=0, column=0, sticky=(tk.N, tk.S, tk.E, tk.W)) self.columnconfigure(2, weight=1) self.rowconfigure(5, weight=1) @@ -75,10 +79,14 @@ def create_bindings(self): def populate_comboboxes(self): self.cryptOptionCombobox.state(('readonly',)) self.dataOptionCombobox.state(('readonly',)) + self.nameCryptoOptionCombobox.state(('readonly',)) self.cryptOptionCombobox.config(values=["加密", "解密", "加密预览", "解密预览"]) self.dataOptionCombobox.config(values=["字符串", "文件", "文件夹"]) + self.nameCryptoOptionCombobox.config(values=["修改文件名", "保持文件名"]) set_combobox_item(self.cryptOptionCombobox, "加密", True) set_combobox_item(self.dataOptionCombobox, "字符串", True) + set_combobox_item(self.nameCryptoOptionCombobox, "修改文件名", True) + self.nameCryptoOptionCombobox["state"] = "disable" # 禁用加密解密按钮,开启进度条 def disable_crypto_button(self, event=None): @@ -99,9 +107,11 @@ def data_choose_event(self, event=None): if self.dataOption.get() == "字符串": self.fileFromChooseButton["state"] = "disable" self.fileToChooseButton["state"] = "disable" + self.nameCryptoOptionCombobox["state"] = "disable" elif self.dataOption.get() == "文件" or self.dataOption.get() == "文件夹": self.fileFromChooseButton["state"] = "normal" self.fileToChooseButton["state"] = "normal" + self.nameCryptoOptionCombobox["state"] = "readonly" # 设置路径输入是否可用 def crypt_choose_event(self, event=None): @@ -147,6 +157,7 @@ def converter(self): password = self.passwordEntry.get() crypto_option = self.cryptOption.get() data_option = self.dataOption.get() + is_handle_name = True if self.nameOption.get() == "修改文件名" else False if not password: tkmessagebox.showerror("错误", "密码不能为空!") @@ -179,15 +190,15 @@ def converter(self): return # 为了不阻塞窗口主程序,使用多线程加密或解密文件 if crypto_option == "加密": - FileHandle(self, "encrypt", input_text, output_text, password).start() + FileHandle(self, "encrypt", input_text, output_text, password, is_handle_name).start() elif crypto_option == "解密": - FileHandle(self, "decrypt", input_text, output_text, password).start() + FileHandle(self, "decrypt", input_text, output_text, password, is_handle_name).start() elif data_option == "文件夹": if not output_text: tkmessagebox.showerror("错误", "目标不能为空!") return if crypto_option == "加密": - DirHandle(self, "encrypt", input_text, output_text, password).start() + DirHandle(self, "encrypt", input_text, output_text, password, is_handle_name).start() elif crypto_option == "解密": - DirHandle(self, "decrypt", input_text, output_text, password).start() + DirHandle(self, "decrypt", input_text, output_text, password, is_handle_name).start() diff --git a/Util.py b/Util.py index b68c839..59d21f5 100644 --- a/Util.py +++ b/Util.py @@ -35,21 +35,29 @@ def text_decrypt(cipher_text, password): return "输入格式或者密码错误!" -def file_encrypt(file_path, output_dir_path, password): +def file_encrypt(file_path, output_dir_path, password, is_encrypt_name): f_crypto = FileCrypto(password) input_file_name = os.path.split(file_path)[1] - output_path = os.path.join(output_dir_path, StringCrypto(password).encrypt(input_file_name)) + # is_encrypt_name为False时,不加密文件名 + if is_encrypt_name: + output_path = os.path.join(output_dir_path, StringCrypto(password).encrypt(input_file_name)) + else: + output_path = os.path.join(output_dir_path, input_file_name) if os.path.exists(output_path): tkmessagebox.showerror("错误", "加密后输出路径下存在同名文件!") return f_crypto.encrypt(file_path, output_path) -def file_decrypt(file_path, output_dir_path, password): +def file_decrypt(file_path, output_dir_path, password, is_decrypt_name): f_crypto = FileCrypto(password) input_file_name = os.path.split(file_path)[1] try: - output_path = os.path.join(output_dir_path, StringCrypto(password).decrypt(input_file_name)) + # is_decrypt_name为False时,不解密文件名 + if is_decrypt_name: + output_path = os.path.join(output_dir_path, StringCrypto(password).decrypt(input_file_name)) + else: + output_path = os.path.join(output_dir_path, input_file_name) if os.path.exists(output_path): tkmessagebox.showerror("错误", "解密后输出路径下存在同名文件!") return @@ -60,23 +68,37 @@ def file_decrypt(file_path, output_dir_path, password): return "" -def dir_encrypt(dir_path, output_dir_path, password): +def dir_encrypt(dir_path, output_dir_path, password, is_encrypt_name): dir_crypto = DirFileCrypto(password) - output_path = os.path.join(output_dir_path, StringCrypto(password).encrypt(os.path.split(dir_path)[1])) + if is_encrypt_name: + output_path = os.path.join(output_dir_path, StringCrypto(password).encrypt(os.path.split(dir_path)[1])) + else: + output_path = os.path.join(output_dir_path, os.path.split(dir_path)[1]) if os.path.exists(output_path): tkmessagebox.showerror("错误", "加密后输出路径下存在同名文件夹!") return - dir_crypto.encrypt(dir_path, output_dir_path) + # is_encrypt_name为False时,不加密文件和文件夹名 + if is_encrypt_name: + dir_crypto.encrypt(dir_path, output_dir_path) + else: + dir_crypto.encrypt(dir_path, output_dir_path, False) -def dir_decrypt(dir_path, output_dir_path, password): +def dir_decrypt(dir_path, output_dir_path, password, is_decrypt_name): dir_crypto = DirFileCrypto(password) try: - output_path = os.path.join(output_dir_path, StringCrypto(password).decrypt(os.path.split(dir_path)[1])) + if is_decrypt_name: + output_path = os.path.join(output_dir_path, StringCrypto(password).decrypt(os.path.split(dir_path)[1])) + else: + output_path = os.path.join(output_dir_path, os.path.split(dir_path)[1]) if os.path.exists(output_path): tkmessagebox.showerror("错误", "解密后输出路径下存在同名文件夹!") return - dir_crypto.decrypt(dir_path, output_dir_path) + # is_decrypt_name为False时,不解密文件和文件夹名 + if is_decrypt_name: + dir_crypto.decrypt(dir_path, output_dir_path) + else: + dir_crypto.decrypt(dir_path, output_dir_path, False) except Exception as e: logging.warning("Convert error: ", e) tkmessagebox.showerror("错误", "输入文件格式或者密码错误!") @@ -84,13 +106,14 @@ def dir_decrypt(dir_path, output_dir_path, password): class FileHandle(threading.Thread): - def __init__(self, main_window, mode, file_path, output_dir_path, password): + def __init__(self, main_window, mode, file_path, output_dir_path, password, is_handle_name): threading.Thread.__init__(self) self.main_window = main_window self.mode = mode self.file_path = file_path self.output_dir_path = output_dir_path self.password = password + self.is_handle_name = is_handle_name def run(self): if not os.path.exists(self.file_path): @@ -104,20 +127,21 @@ def run(self): # 发送消息给主窗口,禁用按钮 self.main_window.event_generate("<>", when="tail") if self.mode == "encrypt": - file_encrypt(self.file_path, self.output_dir_path, self.password) + file_encrypt(self.file_path, self.output_dir_path, self.password, self.is_handle_name) elif self.mode == "decrypt": - file_decrypt(self.file_path, self.output_dir_path, self.password) + file_decrypt(self.file_path, self.output_dir_path, self.password, self.is_handle_name) self.main_window.event_generate("<>", when="tail") class DirHandle(threading.Thread): - def __init__(self, main_window, mode, dir_path, output_dir_path, password): + def __init__(self, main_window, mode, dir_path, output_dir_path, password, is_handle_name): threading.Thread.__init__(self) self.main_window = main_window self.mode = mode self.dir_path = dir_path self.output_dir_path = output_dir_path self.password = password + self.is_handle_name = is_handle_name def run(self): if not os.path.exists(self.dir_path): @@ -131,9 +155,9 @@ def run(self): # 发送消息给主窗口,禁用按钮 self.main_window.event_generate("<>", when="tail") if self.mode == "encrypt": - dir_encrypt(self.dir_path, self.output_dir_path, self.password) + dir_encrypt(self.dir_path, self.output_dir_path, self.password, self.is_handle_name) elif self.mode == "decrypt": - dir_decrypt(self.dir_path, self.output_dir_path, self.password) + dir_decrypt(self.dir_path, self.output_dir_path, self.password, self.is_handle_name) self.main_window.event_generate("<>", when="tail") @@ -169,4 +193,4 @@ def process_directory(self, parent, path, name_handle_func): self.process_directory(oid, abspath, name_handle_func) else: name = name_handle_func(os.path.basename(path)) - self.tree.insert(parent, 'end', text=name, open=False) + self.tree.insert(parent, 'end', text=name, open=False) \ No newline at end of file diff --git a/libs/CFCrypto.py b/libs/CFCrypto.py index bed6826..782d410 100644 --- a/libs/CFCrypto.py +++ b/libs/CFCrypto.py @@ -150,12 +150,20 @@ def handle(input_dir, output_dir, file_handle_func, name_handle_func): file_handle_func(input_file_path, output_file_path) # 加密input_dir文件夹内的所有文件到output_dir - def encrypt(self, input_dir, output_dir): - DirFileCrypto.handle(input_dir, output_dir, self.file_crypto.encrypt, self.string_crypto.encrypt) + # encrypt_name控制是否加密文件或文件夹名 + def encrypt(self, input_dir, output_dir, encrypt_name=True): + if encrypt_name: + DirFileCrypto.handle(input_dir, output_dir, self.file_crypto.encrypt, self.string_crypto.encrypt) + else: + DirFileCrypto.handle(input_dir, output_dir, self.file_crypto.encrypt, lambda name: name) # 解密input_dir文件夹内的所有文件到output_dir - def decrypt(self, input_dir, output_dir): - DirFileCrypto.handle(input_dir, output_dir, self.file_crypto.decrypt, self.string_crypto.decrypt) + # decrypt_name控制是否加密文件或文件夹名 + def decrypt(self, input_dir, output_dir, decrypt_name=True): + if decrypt_name: + DirFileCrypto.handle(input_dir, output_dir, self.file_crypto.decrypt, self.string_crypto.decrypt) + else: + DirFileCrypto.handle(input_dir, output_dir, self.file_crypto.decrypt, lambda name: name) # RSA加密解密类 @@ -235,4 +243,4 @@ def decrypt(self, file_path, output_file_path): data = cipher_aes.decrypt_and_verify(cipher_text, tag) private_file.close() with open(output_file_path, 'wb') as f: - f.write(data) + f.write(data) \ No newline at end of file