150 lines
3.9 KiB
Python
150 lines
3.9 KiB
Python
import string
|
|
|
|
|
|
def _process_vigenere_char(char, key_char, mode):
|
|
if not char.isalpha():
|
|
return char
|
|
|
|
start = ord('A') if char.isupper() else ord('a')
|
|
shift = ord(key_char) - ord('A')
|
|
|
|
if mode == "encrypt":
|
|
processed_char_code = (ord(char) - start + shift) % 26 + start
|
|
elif mode == "decrypt":
|
|
processed_char_code = (ord(char) - start - shift) % 26 + start
|
|
else:
|
|
raise ValueError("无效的模式,必须是 'encrypt' 或 'decrypt'")
|
|
|
|
return chr(processed_char_code)
|
|
|
|
|
|
def vigenere_encrypt(plaintext, key):
|
|
"""
|
|
维吉尼亚加密
|
|
|
|
Args:
|
|
plaintext: 明文字符串
|
|
key: 密钥字符串
|
|
|
|
Returns:
|
|
加密后的字符串
|
|
"""
|
|
processed_key = ''.join(filter(str.isalpha, key.upper()))
|
|
|
|
if not processed_key:
|
|
raise ValueError("密钥不能为空")
|
|
|
|
ciphertext_chars = []
|
|
key_length = len(processed_key)
|
|
key_index = 0
|
|
|
|
for char in plaintext:
|
|
if char.isalpha():
|
|
encrypted_char = _process_vigenere_char(char, processed_key[key_index % key_length], "encrypt")
|
|
ciphertext_chars.append(encrypted_char)
|
|
key_index += 1
|
|
else:
|
|
ciphertext_chars.append(char)
|
|
|
|
return ''.join(ciphertext_chars)
|
|
|
|
|
|
def vigenere_decrypt(ciphertext, key):
|
|
"""
|
|
维吉尼亚解密
|
|
|
|
Args:
|
|
ciphertext: 密文字符串
|
|
key: 密钥字符串
|
|
|
|
Returns:
|
|
解密后的字符串
|
|
"""
|
|
processed_key = ''.join(filter(str.isalpha, key.upper()))
|
|
|
|
if not processed_key:
|
|
raise ValueError("密钥不能为空")
|
|
|
|
plaintext_chars = []
|
|
key_length = len(processed_key)
|
|
key_index = 0
|
|
|
|
for char in ciphertext:
|
|
if char.isalpha():
|
|
decrypted_char = _process_vigenere_char(char, processed_key[key_index % key_length], "decrypt")
|
|
plaintext_chars.append(decrypted_char)
|
|
key_index += 1
|
|
else:
|
|
plaintext_chars.append(char)
|
|
|
|
return ''.join(plaintext_chars)
|
|
|
|
|
|
def display_vigenere_table():
|
|
"""
|
|
显示维吉尼亚加密表
|
|
"""
|
|
alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
|
|
print("维吉尼亚加密表:")
|
|
print(" " + ' '.join(alphabet))
|
|
print(" +" + "-" * 51)
|
|
|
|
for i, row_start in enumerate(alphabet):
|
|
row = []
|
|
for j in range(26):
|
|
# 计算每个位置的字符
|
|
char = chr((ord(row_start) - ord('A') + j) % 26 + ord('A'))
|
|
row.append(char)
|
|
print(f"{row_start} | {' '.join(row)}")
|
|
print()
|
|
|
|
|
|
def main():
|
|
"""
|
|
主函数:交互式界面
|
|
"""
|
|
print("=== 维吉尼亚加密工具 ===")
|
|
|
|
while True:
|
|
print("\n请选择操作:")
|
|
print("1. 加密")
|
|
print("2. 解密")
|
|
print("3. 显示加密表")
|
|
print("4. 退出")
|
|
|
|
choice = input("请输入选择 (1-4): ").strip()
|
|
|
|
if choice == '1':
|
|
plaintext = input("请输入明文: ").strip()
|
|
key = input("请输入密钥: ").strip()
|
|
|
|
try:
|
|
ciphertext = vigenere_encrypt(plaintext, key)
|
|
print(f"加密结果: {ciphertext}")
|
|
except Exception as e:
|
|
print(f"加密错误: {e}")
|
|
|
|
elif choice == '2':
|
|
ciphertext = input("请输入密文: ").strip()
|
|
key = input("请输入密钥: ").strip()
|
|
|
|
try:
|
|
plaintext = vigenere_decrypt(ciphertext, key)
|
|
print(f"解密结果: {plaintext}")
|
|
except Exception as e:
|
|
print(f"解密错误: {e}")
|
|
|
|
elif choice == '3':
|
|
display_vigenere_table()
|
|
|
|
elif choice == '4':
|
|
print("退出程序。")
|
|
break
|
|
|
|
else:
|
|
print("无效选择,请重新输入。")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main() |