1. 凯撒密码加密与解密
任务目标
实现凯撒密码的加密与解密函数,支持任意整数移位(正数加密、负数解密),并通过已知明文/密文对验证正确性。
实现方案
凯撒密码将字母表中的每个字母替换为向后(或向前)固定位数的字母。本实现仅处理英文字母(A-Z,a-z),保留大小写,非字母字符(空格、数字、标点)原样保留。移位值通过取模26归一化到0~25范围,确保任意整数移位(包括负数)均能正确工作。
完整代码
def caesar_encrypt(plaintext: str, shift: int) -> str:
"""凯撒加密:将每个英文字母向后移动shift位(shift可为任意整数)"""
result = []
shift %= 26 # 归一化,处理任意大或负的移位
for ch in plaintext:
if 'a' <= ch <= 'z':
result.append(chr((ord(ch) - ord('a') + shift) % 26 + ord('a')))
elif 'A' <= ch <= 'Z':
result.append(chr((ord(ch) - ord('A') + shift) % 26 + ord('A')))
else:
result.append(ch) # 非字母字符不变
return ''.join(result)
def caesar_decrypt(ciphertext: str, shift: int) -> str:
"""凯撒解密:将每个英文字母向前移动shift位(即加密的逆操作)"""
return caesar_encrypt(ciphertext, -shift)
# ---- 验证 ----
if __name__ == '__main__':
# 测试用例1:已知明文和移位
plain = "Hello, World! 123"
shift = 3
cipher = caesar_encrypt(plain, shift)
decrypted = caesar_decrypt(cipher, shift)
assert cipher == "Khoor, Zruog! 123", f"加密结果错误: {cipher}"
assert decrypted == plain, f"解密结果错误: {decrypted}"
print(f"明文: {plain}")
print(f"移位: {shift}")
print(f"密文: {cipher}")
print(f"解密: {decrypted}")
# 测试用例2:负移位(等价于解密)
cipher2 = caesar_encrypt("abcXYZ", -2)
assert cipher2 == "yzaVWX", f"负移位加密错误: {cipher2}"
assert caesar_decrypt(cipher2, -2) == "abcXYZ"
print("负移位测试通过")
# 测试用例3:移位超过26(取模)
cipher3 = caesar_encrypt("abc", 26 + 1) # 等价于移位1
assert cipher3 == "bcd", f"大移位错误: {cipher3}"
print("大移位测试通过")
print("全部测试通过")
运行与验证
将代码保存为 caesar.py,在终端执行:
python caesar.py
程序通过断言(assert)自动验证三组测试:
- 已知明文测试:
"Hello, World! 123"移位3,预期密文为"Khoor, Zruog! 123",解密后还原明文。 - 负移位测试:移位-2加密
"abcXYZ",预期得到"yzaVWX",解密还原。 - 大移位测试:移位27(即26+1)加密
"abc",预期与移位1结果相同,为"bcd"。
若所有断言通过,终端输出三组测试的明文/密文信息及"全部测试通过";否则程序抛出AssertionError并终止,说明对应实现有误。
关键说明
- 解密函数直接复用加密函数,传入负移位实现逆操作,避免重复逻辑。
- 移位归一化
shift %= 26保证任意整数(包括负数、超过26的数)都能正确处理。 - 非字母字符(空格、数字、标点)不参与变换,保持原样输出。