如何修复Flet凯撒密码应用的特殊字符解密异常问题?
凯撒密码加解密应用特殊字符处理异常问题
我用Flet开发的凯撒密码应用,目前正在优化Á、Ã这类特殊字符的加解密逻辑。原应用已解决空格问题,现在通过not_alpha函数读取CSV文件中的特殊字符-符号映射关系实现转换,但解密时出现异常:比如解密'Á'得到的结果是'Áuuwony',而非正确的原字符。尝试将cryp_word改为f-string拼接后,特殊字符后无内容显示,找不到同类案例,寻求解决方案。
相关代码
import flet as ft import string import pyperclip3 as pc import pandas shift = 6 alphabet = list(string.ascii_lowercase) # a basic app made in flet def main(page: ft.Page): output = "" # this should un mark one of the boxes. Ex. If I clicked cryp and then decryp, the cryp box should return false. def not_alpha(e, char): """ This should read the csv doc with two columns. One with the "especial letter" and other with the "correspondent It's receives char as parameter """ doc = pandas.read_csv("html.csv") letter = [] new_char = "" for i in doc["Letters"]: letter.append(i) not_letter = [] #create a list with the Letters column for i in doc["Simbols"]: not_letter.append(i) #create a list with the Simbols column char_excetions = zip(letter, not_letter) #put it together for i in char_excetions: # verify each element look for the "especial letter"or "correspondent" if char == str(i[0]): new_char = str(i[1]) elif char == str(i[1]): new_char = str(i[0]) return new_char def crypto(e, text_to_use): """Crypto message """ global shift cryp_word = "" if shift > 25: shift = shift % 25 for char in text_to_use: if char in alphabet: char_index = alphabet.index(char) cryp_char_index = char_index + shift if cryp_char_index > 25: cryp_char_index = cryp_char_index % 25 cryp_word += alphabet[cryp_char_index] else: if char == " ": cryp_word += char else: new_char = not_alpha(e, char) cryp_word += str(new_char) return cryp_word def decrypto(e, text_to_use): """Decypto message """ global shift decrypt_word = "" for char in text_to_use: if char in alphabet: char_index = alphabet.index(char) cryp_char_index = char_index - shift if cryp_char_index > 25: cryp_char_index = cryp_char_index % 25 decrypt_word += alphabet[cryp_char_index] else: if char == " ": decrypt_word += char else: new_char = not_alpha(e, char) decrypt_word += str(new_char) return decrypt_word # will execute the action previously selected. def execute(e): """catch the input and make it works as selected""" text_to_use = list(text.value.lower()) text.value = "" result = "" final_text.disabled = False if cryp.value and text_to_use: decryp.value = False result = crypto(e, text_to_use) if decryp.value and text_to_use: cryp.value = False result = decrypto(e, text_to_use) final_text.value = str(result) output = final_text.value page.update() def copy(e, *output): copied = pc.copy(output) print(copied) page.title = "O segredo de Cesar" page.horizontal_alignment = ft.MainAxisAlignment.CENTER page.horizontal_alignment = ft.MainAxisAlignment.CENTER page.vertical_alignment = ft.MainAxisAlignment.START welcome = ft.Text(" Seja bem-vindo!", text_align=ft.TextAlign.CENTER) cryp = ft.Checkbox(label="Criptografar", value=False) decryp = ft.Checkbox(label="Descriptografar", value=False) text = ft.TextField(label="mensagem", hint_text="Digite ou cole a mensagem aqui", text_align=ft.TextAlign.CENTER, multiline=True, min_lines=1, max_lines=6, border=0) button = ft.ElevatedButton(text="Start", on_click=execute) final_text = ft.TextField("", text_align=ft.TextAlign.CENTER, multiline=True, min_lines=1, max_lines=6, border=0, disabled=True) button_copy = ft.ElevatedButton(text="Copy", on_click=copy) page.add( ft.Row([welcome], alignment=ft.MainAxisAlignment.CENTER), ft.Row([decryp, cryp], alignment=ft.MainAxisAlignment.CENTER), ft.Row([text, button], alignment=ft.MainAxisAlignment.CENTER), ft.Row([final_text, button_copy], alignment=ft.MainAxisAlignment.CENTER) ) ft.app(target=main)
字符映射数据
(('Á', 'Á'), ('É', 'É'), ('Í', ' Í'), ('Ó', 'Ó'), ('Ú', 'Ú'), ('á', ' á'), ('é', 'é'), ('í', 'í'), ('ó', 'ó'), ('ú', 'ú'), ('Â', 'Â'), ('Ê', 'Ê'), ('Ô', 'Ô'), ('â', 'â'), ('ê', ' ê'), ('ô', 'ô'), ('À', ' À'), ('à', ' à'), ('Ü', 'Ü'), ('ü', 'ü'), ('Ç', 'Ç'), ('ç', 'ç'), ('Ã', 'Ã'), ('Õ', 'Õ'), ('ã', 'ã'), ('õ', 'õ'), ('Ñ', 'Ñ'), ('ñ', 'Ñ'), ('&', '>&;;'), ('“', '>";;'), ('‘', ">';;"), ('‘', ">';;"), ('<', '<'), ('>', '>'))
问题根源分析
- 映射逻辑低效且存在缺陷:每次调用
not_alpha都重新读取CSV,遍历映射对时若找不到匹配字符,会返回空字符串而非原字符;同时映射数据中存在多余空格(比如' Í'),导致匹配失败。 - 解密逻辑混淆:
decrypto函数处理特殊字符时直接调用not_alpha,但凯撒解密是针对字母的位移还原,特殊字符需按反向映射处理,当前逻辑混淆了转换与位移的顺序。 - 大小写处理错误:
execute中将输入全转小写,破坏了特殊字符的大小写区分,导致映射匹配失败。 - 映射数据错误:原映射中存在格式错误(比如
('&', '>&;;')应为('&', '&')),直接导致转换异常。
解决方案
1. 预加载映射表并优化匹配逻辑
提前加载CSV并生成加密/解密两个字典,避免重复读取文件,同时清理多余空格:
import pandas as pd # 加载并预处理映射表 def load_mappings(): doc = pd.read_csv("html.csv") # 去除字符和符号中的多余空格 doc["Letters"] = doc["Letters"].str.strip() doc["Simbols"] = doc["Simbols"].str.strip() # 加密映射:特殊字符→HTML符号 encrypt_map = dict(zip(doc["Letters"], doc["Simbols"])) # 解密映射:HTML符号→特殊字符 decrypt_map = dict(zip(doc["Simbols"], doc["Letters"])) return encrypt_map, decrypt_map # 在main函数开头加载映射表 encrypt_map, decrypt_map = load_mappings() # 替换原not_alpha函数 def get_mapped_char(char, is_encrypt): if is_encrypt: return encrypt_map.get(char, char) else: return decrypt_map.get(char, char)
2. 修正加密解密逻辑
调整crypto和decrypto函数,明确特殊字符的转换方向:
def crypto(e, text_to_use): global shift cryp_word = "" shift = shift % 26 # 字母共26个,取余更准确 for char in text_to_use: if char in alphabet: char_index = alphabet.index(char) cryp_char_index = (char_index + shift) % 26 cryp_word += alphabet[cryp_char_index] elif char == " ": cryp_word += char else: cryp_word += get_mapped_char(char, is_encrypt=True) return cryp_word def decrypto(e, text_to_use): global shift decrypt_word = "" shift = shift % 26 for char in text_to_use: if char in alphabet: char_index = alphabet.index(char) cryp_char_index = (char_index - shift) % 26 # 处理负数索引情况 if cryp_char_index < 0: cryp_char_index += 26 decrypt_word += alphabet[cryp_char_index] elif char == " ": decrypt_word += char else: decrypt_word += get_mapped_char(char, is_encrypt=False) return decrypt_word
3. 修复大小写处理
execute函数中取消强制转小写,保留原字符的大小写:
def execute(e): text_to_use = list(text.value) # 移除.lower() text.value = "" result = "" final_text.disabled = False if cryp.value and text_to_use: decryp.value = False result = crypto(e, text_to_use) if decryp.value and text_to_use: cryp.value = False result = decrypto(e, text_to_use) final_text.value = result page.update()
4. 修正复制函数逻辑
原复制函数参数错误,调整为直接获取结果文本:
def copy(e): pc.copy(final_text.value) # 新增复制提示 page.snack_bar = ft.SnackBar(ft.Text("已复制到剪贴板")) page.snack_bar.open = True page.update()
5. 修正映射数据错误
将原映射中的错误条目修正:
('ñ', 'Ñ')→('ñ', 'ñ')('&', '>&;;')→('&', '&')('“', '>";;')→('“', '“')('‘', ">';;")→('‘', '‘')
内容的提问来源于stack exchange,提问作者Milla Dma
相关产品推荐
相关产品推荐

