Python 3.12 实现古典密码:5行代码复现凯撒与维吉尼亚加密

在数字化时代,密码学不仅是信息安全的基础,更是一种充满魅力的智力游戏。当我们用现代编程语言Python来重现那些曾经保护过国家机密的古典密码算法时,不仅能感受到历史的厚重,还能体会到算法设计的精妙。本文将带你用Python 3.12的最新特性,仅用5行核心代码实现凯撒密码和维吉尼亚密码的完整加密解密功能。

1. 密码学入门:从凯撒密码开始

凯撒密码得名于古罗马军事家尤利乌斯·凯撒,他在战争中用这种密码与将军们通信。其原理简单却有效:将字母表中的每个字母移动固定的位数。例如,当偏移量为3时,A变成D,B变成E,以此类推。

def caesar_cipher(text, shift, mode='encrypt'):
    if mode == 'decrypt': shift = -shift
    return ''.join(chr((ord(char) - 65 + shift) % 26 + 65) if char.isupper() else 
                   chr((ord(char) - 97 + shift) % 26 + 97) if char.isalpha() else char 
                   for char in text)

这段代码充分利用了Python的生成器表达式和三元运算符,实现了加密解密一体化。核心逻辑在于:

  1. 将字符转换为ASCII码值
  2. 根据大小写调整到0-25范围
  3. 应用位移并取模保证循环
  4. 转换回字符

测试用例

plaintext = "Attack at dawn!"
key = 5
ciphertext = caesar_cipher(plaintext, key)
# 输出: 'Fyyfhp fy ifbs!'
decrypted = caesar_cipher(ciphertext, key, 'decrypt')
# 输出: 'Attack at dawn!'

注意:古典凯撒密码通常只处理字母字符,标点符号和空格保持不变。这也是密码学中的一个重要原则——保持数据的可读性结构。

2. 维吉尼亚密码:多表代换的经典

维吉尼亚密码诞生于16世纪,相比凯撒密码的单表替换,它采用了多表替换机制,显著提高了安全性。其核心思想是使用一个关键词作为密钥,明文中不同位置的字母使用密钥中对应字母决定的凯撒密码进行加密。

加密过程示例

明文 A T T A C K
密钥 L E M O N L
密文 L X F O P V

Python实现同样简洁:

def vigenere_cipher(text, key, mode='encrypt'):
    key_repeated = (key * ((len(text) // len(key)) + 1))[:len(text)]
    return ''.join(caesar_cipher(t, ord(k) - 65 if k.isupper() else ord(k) - 97, mode) 
                   if t.isalpha() else t for t, k in zip(text, key_repeated))

这段代码的巧妙之处在于:

  1. 通过字符串乘法生成足够长的重复密钥
  2. 使用zip函数将明文和密钥字符配对
  3. 对每对字符应用调整后的凯撒密码
  4. 保留非字母字符原样

性能优化技巧

# 预计算密钥的位移量,避免循环中重复计算
key_shifts = [ord(k) - 65 if k.isupper() else ord(k) - 97 for k in key]
key_len = len(key_shifts)
return ''.join(caesar_cipher(t, key_shifts[i % key_len], mode) if t.isalpha() else t 
               for i, t in enumerate(text))

3. 密码分析与安全性增强

古典密码虽然已被现代密码学取代,但分析它们的弱点对理解密码学原理至关重要。凯撒密码的主要弱点包括:

  • 密钥空间极小(仅25种可能)
  • 无法抵抗频率分析攻击
  • 保持单字母统计特性

维吉尼亚密码的安全性相对更高,但当密钥长度小于明文时,仍可能被以下方法破解:

  1. Kasiski测试 :寻找重复密文序列推断密钥长度
  2. 重合指数法 :分析字母频率分布
  3. 已知明文攻击 :利用部分已知明文恢复密钥

增强古典密码安全性的实用技巧

  • 在加密前对文本进行预处理(如删除空格、标点)
  • 结合置换密码打乱字母顺序
  • 使用非字母符号扩展字符集
  • 采用多重加密(如先用维吉尼亚再用凯撒)

4. 现代Python特性在密码实现中的应用

Python 3.12引入了一些新特性,可以让我们的密码实现更加优雅:

类型注解增强

from typing import Literal

def cipher(
    text: str, 
    key: str | int, 
    mode: Literal['encrypt', 'decrypt'] = 'encrypt'
) -> str:
    """支持更精确的类型提示"""

模式匹配简化逻辑

match mode:
    case 'encrypt': shift = shift
    case 'decrypt': shift = -shift
    case _: raise ValueError("模式必须是'encrypt'或'decrypt'")

性能对比测试

from timeit import timeit

setup = "from __main__ import caesar_cipher; text='A'*1000"
timeit("caesar_cipher(text, 5)", setup=setup, number=1000)
# 输出约0.15秒处理1000次千字加密

实际项目中,我们可以将这些密码函数封装为类,提供更完整的接口:

class ClassicalCipher:
    __slots__ = ('_key',)  # 优化内存使用
    
    def __init__(self, key: str | int):
        self._key = key
    
    @staticmethod
    def _process_char(char: str, shift: int) -> str:
        """处理单个字符的加解密"""
        if char.isupper():
            return chr((ord(char) - 65 + shift) % 26 + 65)
        elif char.islower():
            return chr((ord(char) - 97 + shift) % 26 + 97)
        return char
    
    def encrypt(self, plaintext: str) -> str:
        """加密接口"""
    
    def decrypt(self, ciphertext: str) -> str:
        """解密接口"""

这种面向对象的封装方式更适合实际应用,也便于扩展新的密码算法。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐