Skip to content

Commit

Permalink
增加了文件或文件名加密解密选项
Browse files Browse the repository at this point in the history
  • Loading branch information
cforth committed Sep 17, 2017
1 parent b237a29 commit 70078d1
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 33 deletions.
33 changes: 22 additions & 11 deletions MainWindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand All @@ -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):
Expand All @@ -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):
Expand Down Expand Up @@ -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("错误", "密码不能为空!")
Expand Down Expand Up @@ -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()
58 changes: 41 additions & 17 deletions Util.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -60,37 +68,52 @@ 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("错误", "输入文件格式或者密码错误!")
return ""


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):
Expand All @@ -104,20 +127,21 @@ def run(self):
# 发送消息给主窗口,禁用按钮
self.main_window.event_generate("<<DisableCrypto>>", 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("<<AllowCrypto>>", 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):
Expand All @@ -131,9 +155,9 @@ def run(self):
# 发送消息给主窗口,禁用按钮
self.main_window.event_generate("<<DisableCrypto>>", 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("<<AllowCrypto>>", when="tail")


Expand Down Expand Up @@ -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)
18 changes: 13 additions & 5 deletions libs/CFCrypto.py
Original file line number Diff line number Diff line change
Expand Up @@ -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加密解密类
Expand Down Expand Up @@ -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)

0 comments on commit 70078d1

Please sign in to comment.