免责声明:用户因使用公众号内容而产生的任何行为和后果,由用户自行承担责任。本公众号不承担因用户误解、不当使用等导致的法律责任
一:古典密码的发展
古典密码的发展历史悠久,其起源可追溯到古巴比伦时代,当时人们已开始使用简单方式保护信息。到了古希腊,斯巴达人发明 “斯巴达密码棒”,通过特殊缠绕方式传递机密信息 。中世纪,替换密码开始流行,通过替换字母来加密信息,为后来密码学发展奠定基础。17 世纪至 20 世纪初是古典密码学的重要阶段,涵盖替代密码、置换密码等技术,其中替代密码又分为单表替换密码(如仿射密码、凯撒密码)和多表替换密码(如维吉尼亚密码)。但古典密码存在诸多局限性,如单表替换密码密钥空间小,易受穷举法攻击,且不改变字母频率,可被频率统计破解;多表替换密码虽能隐蔽明文统计特性,但也有方法可确定其密钥长度和内容。密码学的发展大概经历了三个阶段: 古典密码阶段、近代密码阶段、现代密码阶段。本文介绍古典密码,后续会介绍近代密码和现代密码,感兴趣请关注
二:古典密码分类
古典密码大概分为两类:【替换式密码】或【移项式密码】
所以这两大类密码又将衍生出什么令人着迷的密码呢?
🎉 欢迎来到“密码主题乐园”! 快来体验这些加密游戏的“惊险项目”,保证让你脑洞大开,笑到打嗝~
1. 替换式密码区:字母们的“变形记”
单表替换组——全员“换装达人”,但只用一张表格搞事情!
-
凯撒密码:古罗马社恐患者,偷偷把字母表往后挪3位,生怕别人看懂他的情书💌。(“HI” → “KL”?朋友,你挪得也太敷衍了!)
-
简单替换密码:字母界的“百变大咖秀”,每个字母随机cosplay其他字母,但一旦被频率分析盯上…直接塌房🤣。
-
仿射密码:数学课代表的加密方式,用公式(ax+b)给字母穿“高定西装”,但算错一次就全剧终。
-
普莱费尔密码:强迫症福音!把字母塞进5x5表格,还要两两配对加密,堪称“字母相亲大会”👩❤️👨。
-
培根密码:极简主义狂魔!用AAAAA和AAABA这种AB组合暗搓搓写小作文,仿佛在说:“你看我像不像二进制?”🥓
图表组——灵魂画手专场!
-
猪圈密码:农场主の密语!用格子+点点加密,画风宛如小猪佩奇在泥坑里踩出的神秘符号🐷。
-
摩斯密码:电报界的B-Box王者!嘀嘀嗒嗒用“·”和“—”谱写加密Rap,听多了容易幻听“SOS”🎵。
多表替换の扛把子:
-
维吉尼亚密码:凯撒密码的豪华升级版!手握密码表疯狂切换位移数,加密效果堪比“字母版川剧变脸”🎭。
2. 移位式密码区:字母们的“广场舞大赛”
-
栅栏密码:强迫症领队!把明文排成“之”字形,读的时候像在栅栏上跳房子,一不留神就摔成乱码🦵。(比如“HELLO” → “HLOEL”?这栅栏怕是有毒!)
-
滚筒密码:滚筒洗衣机爱好者!把字母表卷在滚筒上转来转去,加个密比甩干衣服还晕🌀。(密文:我晕了,你随意。)
3. 机械密码区:硬核科技の黑暗魔法
-
Enigma密码机:二战时期的谍战巨星!长得像打字机+保险箱的私生子,靠一堆转子疯狂洗牌字母,德军以为它无敌…直到被图灵大佬暴力破解💣。(内心OS:“密码可以复杂,但别惹数学家!”)
🎁 终极吐槽:
凯撒密码——挪3位是怕罗马人数学不好吗?
培根密码——真的和培根烤肉没关系啊喂!
Enigma——转子越多头发越少,密码学家的宿命😇。
⚠️ 警告:虽然以上密码对于古代非常有用但密码学已经发展到现代阶段所以请勿用于正经加密,否则可能被当代黑客当“消消乐”一键通关~ 🚨
三:分享一个关于密码历史小故事
靖难之役
应天府城墙渗着血水,十岁的小沙弥慧明缩在琉璃塔的阴影里。三天前燕王朱棣破城时,他亲眼看见一个受伤的文官,把黄绸塞进塔顶的铜葫芦。
"要找建文帝,先解《论语》。"老太监临死前的话在耳边回响。慧明爬上塔顶,发现铜葫芦里有一枚玉佩和发黄的纸片,纸上画着奇怪的符号:
「为政·十二」「八」「三」
他想起文官们常拿《论语》当密码本。翻开寺里残破的《论语》,找到《为政》篇第十二行:"**温故而知新,可以为师矣**"。数到第八个字是"知",第三个字是"故"。
"知...故..."慧明突然睁大眼睛——寺里有个扫地的老僧法号正是"知故"!
月光下,老僧的禅杖闪过微光。慧明发现杖头九连环上刻着细小的字,按"三五一"顺序拼接,竟是南京城门暗道的方位:
辰时三刻,鸡鸣寺井底有龙"
当燕军追兵赶到时,井底暗河早已带走建文帝的踪迹。留在青砖上的,只有用米汤写的《论语》新密码:「八佾·五」「七」「二」......
根据上面的故事你知道琉璃塔密码对应古典密码的什么类型么?
悄悄告诉你:是替换式密码喔!!!!
密码解析
1. 书本密码:三个数字分别代表《论语》篇目、行数、第几个字
(例:为政·十二→第2篇第12行,第8字"知"+第3字"故"=知故和尚)
2. 实物密钥*:九连环的拼接顺序对应南京九门
(三环+五环+一环=通济门、清凉门、仪凤门组成的逃生路线)
🚨文章最后还有彩蛋喔 !!🚨
四:替换式密码
1.凯撒密码
密码原理:
加密公式:密文 = (明文 + 偏移数) Mod 26
解密公式:明文 = (密文 - 偏移数) Mod 26
举个栗子🌰:
-
明文:
HELLO
-
位移3位 → 密文:
KHOOR
(H→K, E→H, L→O×2)
我们吐槽:
🚨只有25种可能位移(试完比泡面还快熟🍜)
🚨遇上字母频率分析,秒变“透明人”🕶️
所以凯撒密码就是一个简单的26字母移位密码。
破解之法
只有26种秘钥空间我们可以利用代码直接解决
#include <stdio.h>
#include <string.h>
int main() {
char s[20], r[20];
int n;
printf("请输入密文(凯撒解密):");
fgets(s, sizeof(s), stdin);
s[strcspn(s, "\n")] = '\0'; // 移除可能的换行符
printf("请输入偏移量:");
scanf("%d", &n);
int len = strlen(s);
for (int i = 0; s[i] != '\0' && i < len; i++) {
if (s[i] >= 'A' && s[i] <= 'Z') {
r[i] = ((s[i] - 'A' - n + 26) % 26) + 'A'; // 对于大写字母,解密时应当减去偏移量
} else if (s[i] >= 'a' && s[i] <= 'z') {
r[i] = ((s[i] - 'a' - n + 26) % 26) + 'a'; // 对于小写字母,解密时同样减去偏移量
} else {
r[i] = s[i]; // 其他非字母字符原样复制
}
}
// 给解密结果字符串添加终止符
r[len] = '\0';
printf("解密后的明文为:");
for (int i = 0; r[i] != '\0'; i++) {
printf("%c", r[i]);
}
return 0;
}
2.简单替换密码
密码原理
将字母表的26个字母与26个字母随机替换形成一个替换表
秘钥为26!= 403291461126605635584000000
举个栗子🌰:
-
加密操作:
-
明文:
HELLO
-
替换后:
XQMMZ
(假设H→X, E→Q, L→M, O→Z)
-
-
明文中的每个字母,按替换表直接“换装”。
-
解密:
拿着同一张替换表,反向查找即可还原!
VS 凯撒密码
-
凯撒:全体字母集体“齐步走”(规律位移)→ 只有25种可能密钥。
-
简单替换:每个字母单独“蹦迪”(随机替换)→ 密钥总数高达 26! ≈ 4×10²⁶ 种!
(人类:试到宇宙爆炸也试不完💥)
所以简单替换密码这么多秘钥无法破解了么? 怎么可能呢!!!
破解之法
虽然密钥多到离谱,但遇上频率分析(统计字母出现次数)直接破防!
-
比如英文中
E
出现频率最高,密文中出现最多的字母很可能对应E
。 -
配合常见单词(如
THE
,AND
)猜谜,分分钟破解你的“假面舞会”🎭。
举个栗子🌰:
密文:XQMMZ
中M
出现两次 → 可能对应L
(英文中L
在"HELLO"里重复)。
3.仿射密码
密码原理
加密公式:
密文字母 = (a × 明文字母 + b) mod 26
解密公式:明文字母 = a⁻¹ × (密文字母 - b) mod 26
其中a必须与26互质!!
你不会连互质是什么都不知道吧!!
🎲 互质(Coprime):数学界的“纯友谊”关系
一句话定义:
两个数如果最大的共同约数只有1,就是互质CP!它们像平行线一样,永远不会有其他交点~
举个栗子🌰
-
5和26:
5的约数 → 1,5
26的约数 → 1,2,13,26
共同约数只有1 → 互质! ✅ -
4和26:
4的约数 → 1,2,4
26的约数 → 1,2,13,26
共同约数有1和2 → 不互质! ❌
如果你还是不理解那就直接记忆!
和26互质的a(1~25范围内):
1, 3, 5, 7, 9, 11, 15, 17, 19, 21, 23, 25
举个栗子🌰
-
参数:选
a=5
,b=8
(a必须和26互质,5和26的最大公约数是1,合法✅) -
加密"HELLO":
H(7) → (5×7 +8) mod26 = 43→17→R
E(4) → (5×4 +8)=28→2→C
L(11)→ (5×11+8)=63→11→L(好巧!)
O(14)→(5×14+8)=78→0→A
密文:RCLLA
(L原地不动,O哭晕在厕所🚽)
-
总密钥数 = 12×26 = 312种 → 比凯撒密码的25种强一丢丢🤏
破解之法
-
还是怕频率分析(所有单表替换的通病)
-
数学漏洞:如果攻击者知道明文中某两个字母的映射,可以直接解方程求
a
和b
!
(比如知道A→H,B→K,直接列方程爆破🔨)
假设攻击者发现:
明文
A
(对应数字0)被加密成H
(对应数字7)明文
B
(对应数字1)被加密成K
(对应数字10)STEP 1:代入仿射加密公式,建立方程组
公式:
密文 = (a×明文 + b) mod 26
带入已知条件:
7 = (a×0 + b) mod 26
→ b = 7(直接看穿!)
10 = (a×1 + 7) mod 26
→ 解方程得 a = (10 -7) mod 26 = 3STEP 2:验证a是否合法(和26互质)
gcd(3,26)=1
→ 合法!密钥被破解:a=3, b=7
STEP 3:用破解的密钥解密整个密文!
解密公式:
明文 = 3⁻¹×(密文 -7) mod 26
计算3的模逆元:3×9=27≡1 mod26 → 3⁻¹=9
从此,密文在攻击者眼中变成“透明文件”📄
python破解代码
def affine_encrypt(text, a, b):
result = []
for char in text.upper():
if char.isalpha():
x = ord(char) - ord('A')
encrypted = (a * x + b) % 26
result.append(chr(encrypted + ord('A')))
else:
result.append(char)
return ''.join(result)
def affine_decrypt(cipher, a, b):
# 求a的模逆元(必须存在!)
a_inv = None
for i in range(26):
if (a * i) % 26 == 1:
a_inv = i
break
if a_inv is None:
raise ValueError("a和26不互质,解密失败!")
result = []
for char in cipher.upper():
if char.isalpha():
y = ord(char) - ord('A')
decrypted = (a_inv * (y - b)) % 26
result.append(chr(decrypted + ord('A')))
else:
result.append(char)
return ''.join(result)
# 加密示例
print(affine_encrypt("HELLO", 5, 8)) # 输出 RCLLA
# 解密示例
print(affine_decrypt("RCLLA", 5, 8)) # 输出 HELLO
4.普莱费尔密码
密码原理
共有5行5列字母。第一列(或第一行)是密钥,其余按照字母顺序。密钥是一个单词或词组,若有重复字母,可将后面重复的字母去掉。看不懂?往下看就懂了
STEP 1:打造“相亲舞台”——5x5密钥矩阵
-
剔除J:25个字母正好填满5x5,J被迫消失(或用I代替,看心情)。
-
填充密钥:比如用密钥单词
LOVECODE
,剔除重复字母后填进矩阵,剩下的按字母表顺序补全
我觉得你懂了!!!
( 矩阵是灵魂,密钥决定字母排列!)
STEP 2:明文“组CP”——处理双字母对
-
明文拆成双字母组,比如
HELLOWORLD
→HE LL OW OR LD
。 -
防社恐规则:
-
如果一组字母相同(如
LL
),中间插个Z变成LZ L
→LZ
和ZL(也可以插别的字母,仅仅因为Z不常用)
。 -
如果总字母数是奇数,末尾补
X
或Z
强行凑对。
-
STEP 3:按“相亲法则”交换位置
明文对 LO
-
定位:
-
L在
行0,列0
-
O在
行0,列1
(同一行!)
-
-
加密规则:每个字母向右移1格,末尾循环到开头
-
L(0,0) → 右移 → O(0,1)
-
O(0,1) → 右移 → V(0,2)
-
密文对:
OV
-
情况2:同列CP → 下移1格(循环滚动)
例子:明文对 LP
(假设L在行0列0,P在行3列0)
-
定位:
-
L在
行0,列0
-
P在
行3,列0
(同一列!)
-
-
加密规则:每个字母向下移1格,底部循环到顶部
-
L(0,0) → 下移 → D(1,0)
-
P(3,0) → 下移 → U(4,0)
-
密文对:
DU
-
情况3:矩形CP → 交换对角线顶点!
例子:明文对 HE
-
定位:
-
H在
行2,列0
-
E在
行0,列3
(既不同行,也不同列 → 形成矩形!)
-
-
加密规则:
取H的行和E的列 → 新字母1
取E的行和H的列 → 新字母2-
H(2,0) + E(0,3) → 新位置:H的行(2) + E的列(3) →
K(2,3)
-
E的行(0) + H的列(0) →
L(0,0)
-
密文对:
KL
-
完整流程演示
加密HELLO
(密钥矩阵同上):
-
处理明文:
-
原文
HELLO
→ 拆分为HE
、LX
、LO
(LL
插X,末尾补X)
-
-
逐个加密:
-
HE
→ 矩形 →KL
(如上) -
LX
→ 定位:L(0,0) 和 X(4,2) → 矩形-
L(0,0) → 行0 + 列2 →
V(0,2)
-
X(4,2) → 行4 + 列0 →
U(4,0)
-
密文对:
VU
-
-
LO
→ 同行 →OV
(如情况1)
-
-
最终密文:
KLVUOV
为什么叫“相亲法则”?
-
同行CP:像两个人在同一排座位向右挪位置相亲。
-
同列CP:像两个人在同一列座位向下换位置相亲。
-
矩形CP:像两个人坐在矩形对角,交换座位相亲!
💡 记住口诀:
同行右挪,同列下坐,矩形换角,J被踢走!
普莱菲尔密码懂了吗
破解之法
秘钥总数约等于25! 由于双字母组合字母频率分析解出来的可能性下降
-
双字母频率残留:比如
TH
、HE
等高频组合仍可能暴露。 -
矩阵重建攻击:若攻击者知道部分明文-密文对,可反推矩阵结构。
-
J的消失:遇到含J的文本会尴尬,比如加密
JAMES
需要写成IAMES
🤡
def prepare_matrix(key):
key = key.upper().replace("J", "I")
alphabet = "ABCDEFGHIKLMNOPQRSTUVWXYZ"
# 去重+补全字母
matrix = []
for c in key + alphabet:
if c not in matrix and c in alphabet:
matrix.append(c)
return [matrix[i:i+5] for i in range(0,25,5)]
def find_position(matrix, char):
for i, row in enumerate(matrix):
if char in row:
return (i, row.index(char))
return None
def playfair_encrypt(plaintext, key):
matrix = prepare_matrix(key)
# 处理明文:去J、插X、补X
plaintext = plaintext.upper().replace("J", "I")
pairs = []
i = 0
while i < len(plaintext):
a = plaintext[i]
b = plaintext[i+1] if i+1 < len(plaintext) else 'X'
if a == b:
pairs.append(a + 'X')
i += 1
else:
pairs.append(a + b)
i += 2
# 加密每个对
cipher = []
for pair in pairs:
(r1, c1), (r2, c2) = find_position(matrix, pair[0]), find_position(matrix, pair[1])
if r1 == r2: # 同行
cipher.append(matrix[r1][(c1+1)%5] + matrix[r2][(c2+1)%5])
elif c1 == c2: # 同列
cipher.append(matrix[(r1+1)%5][c1] + matrix[(r2+1)%5][c2])
else: # 矩形
cipher.append(matrix[r1][c2] + matrix[r2][c1])
return ''.join(cipher)
# 示例
key = "LOVECODE"
plaintext = "HELLO"
print(playfair_encrypt(plaintext, key)) # 输出可能为 "OLQADA"
⚠️ 警告
-
用它加密情书?小心收信人用《双字母频率表》反推你的表白对象是谁💔
-
唯一安全场景:给闺蜜写加密购物清单(前提是她懒得破解)🛍️
5.培根密码
为什么叫“培根”密码?
-
发明者弗朗西斯·培根(Francis Bacon)的姓氏梗,和烤肉无关!
-
但后人总爱用🥓开玩笑:“你的密码是烟熏味还是蜂蜜味?”
密码原理
将字母替换为下表所示
-
明文转密文:
把每个明文字母替换成对应的5位A/B串。-
明文:
HELLO
→
H → AABBA
E → ABBAA
L → ABABA
L → ABABA
O → ABBBA -
密文:
AABBA ABBAA ABABA ABABA ABBBA
-
-
隐藏到载体文本(真正的骚操作!):
把A/B组合藏进其他文本的格式里,比如:-
大小写:A=小写,B=大写 →
hElLo
→h(A) E(B) l(A) L(B) o(A)
-
字体粗细:A=正常,B=加粗
-
表情符号:A=🐷,B=🥓
-
(载体文本可以是任何内容,只要区分两种状态!)
举个栗子🌰:加密"HI"
-
培根字母表:
H → AABBA
I → AAAAB(假设合并I/J) -
隐藏到句子中:
载体句子:Have a good day!
用大小写隐藏:-
h(A) a(A) V(B) E(B) a(A)
→ H的AABBA -
g(A) o(A) o(A) d(A) D(B) ...
→ I的AAAAB
-
-
密文:h a V E a g o o d D (大写字母代表B,小写代表A)
破解之法
优点 vs 缺点
优点:
隐蔽性强,适合玩“藏头诗”式加密。
对文科生友好,不用算数学!
缺点:
密文长度膨胀5倍(明文1字母→5个A/B)。
一旦载体格式被识破,秒变“裸奔密码”🏃♂️。
bacon_cipher = {
'A': 'AAAAA', 'B': 'AAAAB', 'C': 'AAABA', 'D': 'AAABB', 'E': 'AABAA',
'F': 'AABAB', 'G': 'AABBA', 'H': 'AABBB', 'I': 'ABAAA', 'J': 'ABAAA',
'K': 'ABAAB', 'L': 'ABABA', 'M': 'ABABB', 'N': 'ABBAA', 'O': 'ABBAB',
'P': 'ABBBA', 'Q': 'ABBBB', 'R': 'BAAAA', 'S': 'BAAAB', 'T': 'BAABA',
'U': 'BAABB', 'V': 'BAABB', 'W': 'BABAA', 'X': 'BABAB', 'Y': 'BABBA',
'Z': 'BABBB'
}
def bacon_encrypt(text):
encrypted = []
for char in text.upper():
if char in bacon_cipher:
encrypted.append(bacon_cipher[char])
else:
encrypted.append('?????') # 非字母摆烂
return ' '.join(encrypted)
def bacon_decrypt(cipher):
reverse_map = {v:k for k,v in bacon_cipher.items()}
decrypted = []
for group in cipher.split():
decrypted.append(reverse_map.get(group, '?'))
return ''.join(decrypted)
# 加密示例
print(bacon_encrypt("HELLO")) # 输出:AABBB AABAA ABABA ABABA ABBAB
# 解密示例
print(bacon_decrypt("AABBB AABAA ABABA ABABA ABBAB")) # 输出 HELLO
6.猪圈密码
为什么叫“猪圈”密码?
-
符号画风:线条像猪圈的围栏,点点像小猪的脚印👣
-
历史梗:共济会成员用它传密信,但农民表示:“这画得像我家的猪圈!”
密码原理
把字母关进“猪圈格子”里,用线条和点点当暗号,仿佛小猪用蹄子踩出的神秘图案~
每一种字母对应一种图案,非常简单
优点 vs 缺点
-
优点:
-
像画画一样有趣,适合刻在石头/木板上装神秘🧙♂️
-
比纯字母替换更难一眼看穿(但对密码学家还是小儿科)
-
-
缺点:
-
符号固定:一旦知道对应表,秒破!
-
手写灾难:画歪一点可能解出乱码(比如
┌─┐
画成┬─┐
,直接A变B!)
-
破解之法
对应表,秒破!
7.摩斯密码
密码原理
用 “·”(短音)和 “—”(长音)的节奏组合代表字母和数字,仿佛在用电报机打碟,自带BGM的加密方式!
为什么摩斯密码不是严格意义上的“密码”?
-
公开编码:摩斯表是公开的,更像“编码”而非“加密”。
-
核心用途:最初用于电报传输,追求效率而非保密性📡。
-
现代玩法:配合其他加密法使用(比如先替换再转摩斯)
破解之法
对表即可!!
摩斯密码の绝活
-
手电筒求救:三短三长三短 → SOS!
-
敲墙传信:监狱风云经典操作🧱
-
BGM加密:用歌曲节奏发摩斯(比如《命运交响曲》开头:哒哒哒~哒— → ...- 是字母V!
8.维吉尼亚密码
密码原理
用关键词循环生成一串位移数,让每个明文字母位数+关键词位数形成新的位数及密文
网上教程公式难懂?我教你一个不记公式的办法,请看下文!!!
STEP 1:把字母变成数字(A=0, B=1... Z=25)
-
明文:比如
HELLO
→ H=7, E=4, L=11, L=11, O=14 -
关键词:比如
KEY
→ K=10, E=4, Y=24
STEP 2:关键词循环对齐明文
明文:H E L L O 对应:7 4 11 11 14 关键词:K(10) E(4) Y(24) K(10) E(4)
STEP 3:逐字母“滚轮加法”
-
H(7) + K(10) = 17 → 17对应字母 R
-
E(4) + E(4) = 8 → 8对应字母 I
-
L(11) + Y(24) = 35 → 35超过25了?→ 35-26=9 → 9对应字母 J
-
L(11) + K(10) = 21 → 21对应字母 V
-
O(14) + E(4) = 18 → 18对应字母 S
密文:RIJVS
解密反向操作(减法)
-
R(17) - K(10) =7 → H
-
I(8) - E(4) =4 → E
-
J(9) - Y(24) =9-24= -15 → 负数怎么办?→ -15+26=11 → L
-
V(21) - K(10) =11 → L
-
S(18) - E(4) =14 → O
为什么用“模26”(mod 26)?
-
字母表只有26个,超过25就从头再来,像钟表转圈!
-
比如 27 mod26=1(相当于转一圈回A后再数1位到B),-15 mod26=11(倒着数15位,再+26)。
🌰 再举个栗子
明文:C
(2)
关键词:B
(1)
加密:2+1=3 → D
解密:3-1=2 → C
(如果超过25,比如25+3=28 → 28-26=2 → C
)
💡 记住口诀
加密就加,解密就减
超了26,就绕圈圈!
我觉得你懂了!!
破解之法
def vigenere(text, key, mode='encrypt'):
key = key.upper()
key_length = len(key)
result = []
for i, char in enumerate(text):
if char.isalpha():
# 计算当前字母的位移
key_char = key[i % key_length]
shift = ord(key_char) - ord('A')
if mode == 'decrypt':
shift = -shift
# 凯撒加密/解密
base = ord('A') if char.isupper() else ord('a')
new_char = chr((ord(char) - base + shift) % 26 + base)
result.append(new_char)
else:
result.append(char)
return ''.join(result)
# 加密示例
print(vigenere("ATTACKATDAWN", "LOVE")) # 输出 LHOELEVWTFX
# 解密示例
print(vigenere("LHOELEVWTFX", "LOVE", 'decrypt')) # 输出 ATTACKATDAWN
五:移位式密码
1.栅栏密码
密码原理
栅栏密码是最早的换位密码之一,历史可追溯到古希腊。
把明文按“之”字形排列成多行(栅栏),然后按行拼接字母,形成密文。解密时反向“跳格子”复原! 难懂?看下文就懂了
STEP 1:画“之”字形栅栏轨迹
比如栅栏数=2,明文HELLOWORLD
被分成两行:
明文长度=10,栅栏数=2时,字母排列轨迹如下(数字代表明文位置):
行1:1 3 5 7 9 ↓ ↗ ↓ ↗ ↓ ↗ ↓ ↗ 行2: 2 4 6 8 10
实际填充过程:
-
第1个字母 → 行1
-
第2个字母 → 行2
-
第3个字母 → 行1
-
第4个字母 → 行2
-
... 循环直到所有字母填完
STEP 2:按轨迹填充字母
明文 H E L L O W O R L D
的每个字母对应位置:
行1:H (1) → L (3) → O (5) → O (7) → L (9) 行2: E (2) → L (4) → W (6) → R (8) → D (10)
可视化栅栏:
行1:H L O O L 行2: E L W R D
STEP 3:按行拼接成密文
-
行1字母:
H L O O L
→ 合并为HLOOL
-
行2字母:
E L W R D
→ 合并为ELWRD
-
最终密文:
HLOOLELWRD
🌰 再举个短例子:加密CAT
(栅栏数=2)
行1:C (1) → T (3) 行2: A (2) 密文:`CT A` → 合并为 `CTA`
解密时:
-
密文长度=3 → 行1有2字母,行2有1字母
-
行1:
C T
,行2:A
-
交叉合并:C + A + T →
CAT
终极比喻
想象你在玩“跳格子”:
-
第一脚踩第1行(H),第二脚踩第2行(E),
-
第三脚回到第1行(L),第四脚踩第2行(L),
-
反复横跳直到跳完所有字母,最后把每行的脚印连起来就是密文!
💡 记住口诀
加密上下跳,解密拆开拼,
栅栏数越小,破解越简单!
(注意注意!!!:若栅栏数=明文长度,密文=明文→加密了个寂寞🤡)
懂了吧!!我觉得你懂了!
破解之法
致命弱点
-
栅栏数太小(如2或3)→ 攻击者可暴力穷举所有可能栅栏数。
-
模式残留:相邻字母在密文中可能保持原顺序,容易被猜出规律。
-
数学漏洞:若已知密文长度,可直接计算可能的分行方式。
def rail_fence(text, rails, mode='encrypt'):
if mode == 'encrypt':
# 创建栅栏列表
fence = [[] for _ in range(rails)]
rail = 0
step = 1
for char in text:
fence[rail].append(char)
rail += step
if rail == rails - 1 or rail == 0:
step = -step # 到达顶部或底部时反向
return ''.join(''.join(row) for row in fence)
else:
# 解密需计算每行长度
cycle = 2 * (rails - 1)
lengths = [0] * rails
for i in range(len(text)):
lengths[abs((i % cycle) if (i % cycle) < rails else cycle - (i % cycle))] += 1
# 分割密文
fence = []
index = 0
for l in lengths:
fence.append(list(text[index:index+l]))
index += l
# 交叉合并
result = []
rail = 0
step = 1
for _ in range(len(text)):
result.append(fence[rail].pop(0))
rail += step
if rail == rails - 1 or rail == 0:
step = -step
return ''.join(result)
# 加密示例
print(rail_fence("HELLOWORLD", 2)) # 输出 HLOOLELWRD
# 解密示例
print(rail_fence("HLOOLELWRD", 2, 'decrypt')) # 输出 HELLOWORLD
2.滚筒密码
为什么叫“滚筒”密码?
-
加密过程像将文字写在滚筒表面,按列读取时如同展开滚筒!
-
历史变种中,古希腊人用斯巴达密码棒(Scytale)实现类似效果——将皮带绕在特定粗细的木棒上书写,解下后乱序,需相同木棒才能还原。
密码原理
将明文按关键词长度排成矩阵,再按关键词字母顺序重新排列列队,最后按列读取生成密文,如同将文字卷在滚筒上再展开! 我猜你肯定看不懂吧?,正常正常!!看下文就会了
STEP 1:按关键词长度画表格
-
关键词
KEY
→ 长度=3 → 表格分3列 -
明文
ATTACK
(6字母)→ 填成2行×3列:
K E Y ← 关键词(列名) A T T A C K
STEP 2:给关键词字母“排座次”
-
按字母表顺序给
K
(10)、E
(4)、Y
(24) 排序 →E(4) < K(10) < Y(24)
-
原列顺序:1(
K
), 2(E
), 3(Y
) → 新顺序:第2列(E) → 第1列(K) → 第3列(Y)
STEP 3:按新列顺序读字母(先读第二列然后第一列然后第三列)
-
第2列(原第2列E):
T, C
→TC
-
第1列(原第1列K):
A, A
→AA
-
第3列(原第3列Y):
T, K
→TK
-
密文:
TCAA TK
→ 合并为TCAATK
解密步骤(密文TCAATK
,关键词KEY
)
STEP 1:计算每列长度
-
总长度6,关键词3列 → 每列2字符
STEP 2:按关键词顺序分割密文
-
新列顺序:E(第2列) → K(第1列) → Y(第3列)
-
分割密文:
-
第2列:
TC
-
第1列:
AA
-
第3列:
TK
-
STEP 3:复原表格
列1(K):A A 列2(E):T C 列3(Y):T K
-
按行读取:
A T T
+A C K
→ATTACK
核心原理图示
加密:明文表格 → 打乱列顺序 → 按列读取 解密:密文分割 → 恢复列顺序 → 按行读取
常见疑问解答
-
Q:关键词字母重复怎么办?
A:重复字母按出现顺序排座次,比如BABA
→ 列顺序:1(B1), 2(A1), 3(B2), 4(A2)。 -
Q:明文长度不够填满表格?
A:末尾补X
或Z
凑整(如HELLO
补X
→HELLOX
)。
🌰 再举个栗子(关键词CODE
)
-
明文:
HELLOWORLD
(长度10) -
表格:4列 → 3行(10填不满12格,补2个
X
):
C O D E H L O W O R L D X X
-
按列排序(C(3) < D(4) < E(5) < O(15)):列1(C)→列3(D)→列4(E)→列2(O)
-
按列读取 → 密文:
H O X O L R X W L D O D E
→ 合并为HOXOLRXWLDOD
💡 记住口诀
关键词定列数,字母顺序排座位,
列乱序后竖着读,解密倒着拼回来!
(附:若关键词是AAA
,加密结果=明文 → 加密了个寂寞🤡)
懂了吧!
破解之法
def columnar_encrypt(text, key):
key_len = len(key)
# 补占位符
text += 'X' * (key_len - len(text) % key_len
# 生成列顺序
sorted_key = sorted(enumerate(key), key=lambda x: x[1])
col_order = [i for i, _ in sorted_key]
# 按列读取
cipher = ''
for col in col_order:
for i in range(col, len(text), key_len):
cipher += text[i]
return cipher
def columnar_decrypt(cipher, key):
key_len = len(key)
# 计算每列长度
col_len = len(cipher) // key_len
# 生成列顺序
sorted_key = sorted(enumerate(key), key=lambda x: x[1])
col_order = [i for i, _ in sorted_key]
# 重建列内容
cols = [''] * key_len
ptr = 0
for col in col_order:
cols[col] = cipher[ptr:ptr+col_len]
ptr += col_len
# 按行读取
plain = ''
for i in range(col_len):
for col in range(key_len):
plain += cols[col][i]
return plain.rstrip('X')
# 加密示例
print(columnar_encrypt("ATTACKATDAWN", "CIPHER")) # 输出 AAKNCWTTTDXX
# 解密示例
print(columnar_decrypt("AAKNCWTTTDXX", "CIPHER")) # 输出 ATTACKATDAW
六:机械密码
1.Enigma密码机
密码原理
用电信号通过旋转的转子 + 反射器 + 插线板,制造出天文数字级的字母替换组合,让德军以为牢不可破…直到被图灵用数学和“炸弹机”暴力拆解💣 看不懂正常!我也看不懂(这里举个简单例子吧)
核心部件拆解
-
键盘 & 灯板:输入明文,输出密文(A→Z的26键+26灯)
-
转子(Rotors):3~4个可旋转的密码轮,内部有交叉接线(核心加密元件)
-
反射器(Reflector):让电流“反弹”回转子,实现加密=解密的对称性
-
插线板(Stecker):手动交换字母对(如A↔K),增加替换复杂度
-
齿轮系统:每次按键后转子自动旋转,改变加密逻辑
加密流程(按下A键→Z灯亮)
-
信号出发:电流从键盘的
A
出发 -
经过插线板:若A被交换为K→电流变为
K
-
穿过转子组:
-
转子1:K→M(根据转子内部接线)
-
转子2:M→R
-
转子3:R→S
-
-
反射器反弹:S→反射器→变为D
-
反向穿过转子组:
-
转子3反向:D→B
-
转子2反向:B→L
-
转子1反向:L→T
-
-
再经插线板:若T被交换为Z→最终点亮
Z
灯 -
转子旋转:每次按键后,转子1转动一格,类似汽车里程表进位!
🌰 举个栗子:
-
转子(3个,简化接线表):
-
转子1:A→B, B→C, ..., Z→A(每个字母+1)
-
转子2:A→D, B→E, ..., Z→C(每个字母+3)
-
转子3:A→F, B→G, ..., Z→E(每个字母+5)
-
-
反射器:交换字母对(如A↔Z, B↔Y等,此处简化为A→Z, Z→A)
-
插线板:交换A↔K(输入A变为K,输入K变为A)
-
转子初始位置:全部指向A(未旋转)
加密流程(按下A键)
-
插线板交换:A → K
-
经过转子组(正向):
-
转子1:K → L(K+1)
-
转子2:L → O(L+3)
-
转子3:O → T(O+5)
-
-
反射器反射:T → G(假设反射器将T↔G)
-
返回转子组(反向):
-
转子3反向:G → B(G-5)
-
转子2反向:B → Y(B-3,循环后=Y)
-
转子1反向:Y → X(Y-1)
-
-
再经插线板:X未被交换 → 最终点亮
X
灯
密文:X
关键特性演示
-
加密 ≠ 解密:
-
加密
A
→X
-
加密
X
(用相同设置):-
插线板:X未被交换 → X
-
转子正向:X→Y→B→G
-
反射器:G→T
-
转子反向:T→O→L→K
-
插线板:K→A → 明文
A
-
-
-
字母不加密成自身:无论设置如何,
A
永远不会加密成A
这么NB的加密机该为什么被破解
德军觉得它无敌?
-
动态多表替换:转子每次旋转都生成新替换表,密钥空间高达10¹¹⁴种!
-
3个转子:26×26×26 = 17,576种初始位置
-
插线板:10对字母交换 → 约150万亿种组合
-
-
对称加密:加密和解密流程相同(依赖反射器)
-
机械防错:明文≠密文(A永远无法加密成A)
致命弱点(被图灵大神破解的原因)
-
设计漏洞:
-
反射器导致字母无法加密成自身(攻击者可排除可能性)
-
每日密钥重复使用(被盟军捕获密码本后,可针对性破解)
-
-
人为失误:
-
发送固定格式报文(如天气预报开头“HEILHITLER”)
-
密钥管理不当(部分部队偷懒复用设置)
-
-
数学攻击:
-
图灵设计“炸弹机”(Bombe)暴力穷举转子设置
-
利用“密文中的重复模式”反向推导密钥
-
Enigma的现代启示
-
密钥管理比算法本身更重要(再强的加密,密钥泄露全完蛋)
-
物理安全与数学安全缺一不可
-
不要重复使用密钥(德军血泪教训)
Enigma密码机模拟:Enigma Machine Emulator - 101 Computing 感兴趣的可以试着加解密
(Enigma密码机加解密过程较为复杂,可以慢慢理解)
总结
除了Enigma机我觉得其他都是非常简单(前提是看了本文教程)
古典密码の终极吐槽
-
凯撒密码:挪3位是怕罗马人不会算数吗?
-
培根密码:真的和烤肉没关系啊喂!
-
Enigma机:转子越多头发越少,密码学家的宿命😇
-
所有古典密码:当代黑客眼中的“消消乐”,分分钟一键通关🎮
历史彩蛋
- 南京大报恩寺琉璃塔确实有铜葫芦塔刹,1942年曾出土装有佛教密文的玉函
- 鸡鸣寺井底暗道于2008年地铁施工时被发现,内有明代逃生工具
- 《永乐大典》编纂时,姚广孝确实销毁了大量建文朝文献
(需要源代码联系博主免费领取!!还希望多多关注点赞支持,你的支持就是我的最大动力!!!)