如何避免加密生成退格/删除/空字符导致密文无法正常还原?
替换密码特殊字符问题的解决方案
问题背景
你实现的基于256位ASCII的替换密码,在使用密钥6012加密时生成了包含不可打印控制字符的密文,这些字符在输入/输出过程中被终端或输入函数篡改,导致解密无法还原正确明文。
原始代码
def Encrypt(psw, key): res = "" for i in psw: new_letter = chr((ord(i)+key)%255) if new_letter == '\n': new_letter = '。' res += new_letter return res def Decrypt(psw, key): res = "" for i in psw: if i == '。': i = '\n' old_letter = chr((ord(i)-key)%255) res += old_letter return res if __name__ == "__main__": try: while True: i = input("1 for encryption, 2 for decryption") s = "";k = 0 if i == '1': s = input("Input Plaintext:") k = (int)(input("Input Key:")) print("Ciphertext is:"+Encrypt(s, k)) elif i == '2': s = input("Input Ciphertext:") k = (int)(input("Input Key:")) print("Plaintext is:"+Decrypt(s, k)) else: break except: print("Error")
问题根源
- 原代码用
%255取模,遗漏了ASCII 255的取值范围,应该用%256覆盖完整的0-255 ASCII区间。 - 加密过程中生成的ASCII控制字符(0-31及127)无法被终端正常显示或被
input()函数正确读取,导致密文丢失或篡改,解密时自然无法得到正确明文。
解决办法
最可靠的方案是将密文转换为Base64编码,Base64仅使用可打印的ASCII字符(A-Z、a-z、0-9、+、/、=),完全避免控制字符的问题。以下是修改后的代码:
import base64 def Encrypt(psw, key): # 将明文转为字节流,处理每个字节 plain_bytes = psw.encode('utf-8') cipher_bytes = b"" for byte in plain_bytes: # 使用256取模,覆盖完整ASCII范围 new_byte = (byte + key) % 256 cipher_bytes += bytes([new_byte]) # 转Base64编码为可打印字符串 return base64.b64encode(cipher_bytes).decode('utf-8') def Decrypt(cipher_b64, key): try: # 解码Base64得到加密后的字节流 cipher_bytes = base64.b64decode(cipher_b64) except ValueError: return "错误:密文不是有效的Base64编码" plain_bytes = b"" for byte in cipher_bytes: old_byte = (byte - key) % 256 plain_bytes += bytes([old_byte]) try: # 将字节流转回明文字符串 return plain_bytes.decode('utf-8') except UnicodeDecodeError: return "错误:解密后的字节流无法转为有效UTF-8字符串" if __name__ == "__main__": while True: choice = input("1 加密,2 解密,其他键退出:") if choice == '1': plaintext = input("输入明文:") try: key = int(input("输入密钥:")) ciphertext = Encrypt(plaintext, key) print(f"密文(Base64):{ciphertext}") except ValueError: print("错误:密钥必须是整数") elif choice == '2': cipher_b64 = input("输入密文(Base64格式):") try: key = int(input("输入密钥:")) plaintext = Decrypt(cipher_b64, key) print(f"明文:{plaintext}") except ValueError: print("错误:密钥必须是整数") else: break
修改说明
- 改用字节流处理,避免字符串对控制字符的异常处理逻辑
- 使用
%256取模,覆盖完整的0-255 ASCII区间 - 加密后将字节流转为Base64字符串,确保密文全为可打印字符,传输/输入无丢失
- 解密时先解码Base64,再还原字节流,最后转为明文
- 增加了针对性的错误提示,替换原有的笼统
Error输出
内容的提问来源于stack exchange,提问作者Zhang Fei
相关产品推荐
相关产品推荐

