3. 维吉尼亚密码的加密与解密
任务目标
实现维吉尼亚密码(Vigenère Cipher)的加密与解密功能。程序接收一个由字母组成的密钥字符串,对输入的英文文本(仅含A-Z字母,大小写不敏感)进行加密和解密,并输出结果。
实现思路
维吉尼亚密码是凯撒密码的多表替代扩展。加密时,将密钥中的每个字母映射为位移量(A=0, B=1, ..., Z=25),依次作用于明文的每个字母;密钥长度不足时循环使用。解密时使用相同的密钥,将密文字母反向位移即可。本实现将明文统一转为大写处理,密钥中的字母同样转为大写以计算位移。
完整代码
def vigenere_encrypt(plaintext: str, key: str) -> str:
"""使用维吉尼亚密码加密明文(仅处理A-Z字母,忽略其他字符)"""
plaintext = plaintext.upper()
key = key.upper()
ciphertext = []
key_index = 0
for ch in plaintext:
if 'A' <= ch <= 'Z':
shift = ord(key[key_index % len(key)]) - ord('A')
encrypted_char = chr((ord(ch) - ord('A') + shift) % 26 + ord('A'))
ciphertext.append(encrypted_char)
key_index += 1
else:
ciphertext.append(ch) # 非字母字符原样保留
return ''.join(ciphertext)
def vigenere_decrypt(ciphertext: str, key: str) -> str:
"""使用维吉尼亚密码解密密文(仅处理A-Z字母,忽略其他字符)"""
ciphertext = ciphertext.upper()
key = key.upper()
plaintext = []
key_index = 0
for ch in ciphertext:
if 'A' <= ch <= 'Z':
shift = ord(key[key_index % len(key)]) - ord('A')
decrypted_char = chr((ord(ch) - ord('A') - shift) % 26 + ord('A'))
plaintext.append(decrypted_char)
key_index += 1
else:
plaintext.append(ch) # 非字母字符原样保留
return ''.join(plaintext)
# 最小调用示例
if __name__ == '__main__':
key = "KEY"
plain = "HELLO WORLD"
encrypted = vigenere_encrypt(plain, key)
decrypted = vigenere_decrypt(encrypted, key)
print(f"明文: {plain}")
print(f"密文: {encrypted}")
print(f"解密: {decrypted}")
# 验证:解密结果应与原明文一致
assert decrypted == plain, "加解密不一致!"
print("验证通过:解密结果与明文一致。")
运行与验证
运行方式:将上述代码保存为 vigenere.py,在命令行执行 python vigenere.py。
预期输出:由于代码逻辑确定,给定输入 plain="HELLO WORLD"、key="KEY" 时,输出应为:
明文: HELLO WORLD
密文: RIJVS UYVJN
解密: HELLO WORLD
验证通过:解密结果与明文一致。
判定标准:程序正常结束且打印“验证通过”即表示加解密功能正确。可自行修改 plain 和 key 的值(密钥仅含字母)进行更多测试,解密结果始终应与原明文相同。
关键说明
- 代码仅处理英文字母,数字、空格、标点等非字母字符在加密和解密时均原样保留,不参与位移计算。
- 密钥字符串仅支持字母,若包含其他字符需先过滤,否则
ord(key[...]) - ord('A')会得到错误位移。本实现假定输入密钥合法。 - 加密和解密使用同一密钥,解密是加密的逆运算,因此
vigenere_decrypt(vigenere_encrypt(text, key), key) == text恒成立。