跳轉到

2.1 凱薩密碼與移位密碼#

概念說明#

凱薩密碼是最古老的替代密碼之一:把明文中每個字母在字母表上往後平移固定 k 位。例如 k=3 時,A→D、B→E、Z→C。它是一種單表替代密碼——整份訊息從頭到尾使用同一張替換表。

廣義的移位密碼(shift cipher)就是把凱薩密碼的位移量一般化為任意整數 k(0~25)。金鑰空間只有 26 個,小到可以人工窮舉,因此它從來就不是安全密碼;但它是理解「替代」、「金鑰」、「模運算」三個核心概念的最佳起點。

數學描述#

把字母 A~Z 編號為 0~25,則:

  • 加密:C = (P + k) mod 26
  • 解密:P = (C - k) mod 26

其中 mod(取餘數)讓字母繞圈:Z(25) + 1 → A(0)。這是第 8 章「模運算」的第一次登場。

演算法步驟#

  1. 將明文統一轉為大寫、去除非字母字元(或保留原樣只處理字母)。
  2. 對每個字母 p,計算 (字母編號 + k) mod 26。
  3. 將結果編號轉回字母,得到密文。
  4. 解密時以 -k 做同樣的運算即可。

Python 實作#

def shift_encrypt(text: str, k: int) -> str:
    result = []
    for ch in text:
        if ch.isalpha():
            base = ord('A') if ch.isupper() else ord('a')
            result.append(chr((ord(ch) - base + k) % 26 + base))
        else:
            result.append(ch)  # 非字母原樣保留
    return ''.join(result)

def shift_decrypt(text: str, k: int) -> str:
    return shift_encrypt(text, -k)

msg = "The Caesar cipher is easy to break"
ct = shift_encrypt(msg, 3)
print(ct)                    # Wkh Fdhvdu flskhu lv hdvb wr euhdn
print(shift_decrypt(ct, 3))  # 還原明文

# 窮舉攻擊:26 把金鑰全部試一次
for k in range(26):
    pt = shift_decrypt(ct, k)
    if "cipher" in pt:
        print(f"金鑰 = {k}, 明文 = {pt}")
        break

安全性分析#

  • 金鑰空間只有 26:以現代運算力,窮舉不到一毫秒;即使人工,也只有 26 行可讀。這違反了「金鑰空間須足夠大」的基本要求(1.3 節)。
  • 單表替代的統計弱點:即使把金鑰空間擴大(如任意打亂 26 個字母的對應,金鑰空間 26!≈4×10^26),頻率分析仍然有效——因為明文中 E 最常出現的統計特性被原封不動地帶進密文(2.2 節)。
  • 已知明文攻擊直接讀出金鑰:只要知道一組明文—密文對,k = (C - P) mod 26 立即現形。

教學提醒:本節程式碼僅供理解原理,絕不可用於實務保密。

練習#

  1. 用 k=11 加密 ATTACK AT DAWN,再用程式解密驗證。
  2. 拿到一段不知金鑰的移位密文,寫一個「自動破解器」:對所有 26 個 k 計算解密結果,用英文常用字母頻率(如 E、T、A)評分,回傳最可能者。
  3. 若把凱薩密碼改為「每個字母移不同量」(例如依金鑰字串循環取位移量),它就變成了哪一種古典密碼?(提示:下一節會用到)