首页/我的作品/密码学/4.2 矩阵换位:把信息“揉”乱了
密码学:守护数字世界的秘密

4.2 矩阵换位:把信息“揉”乱了

第 23 / 78 篇 · Crazy Boy

栅栏密码只是简单地上下交替排列,它的“揉乱”程度有限——字母的顺序虽然变了,但相邻关系还保留了不少。如果你想要一种更彻底的“揉乱”方式,就像把一张纸条撕碎再拼起来,那么矩阵换位就是你要找的。

矩阵换位的核心思想是:把明文写进一个表格里,然后按照某种规则打乱表格的列,最后再按行读出。这个过程就像你揉面团——先铺平,再折叠,再摊开,原本挨着的两块面可能就被分到天南海北了。

基本操作:先写进去,再读出来

让我们从一个最简单的例子开始。假设我们要加密一句话:WE ARE DISCOVERED FLEE AT ONCE(我们被发现了,立刻逃跑)。先把空格去掉,得到:WEAREDISCOVEREDFLEEATONCE。

第一步,我们需要一个矩阵。矩阵的行数和列数可以任意选择,但通常我们会选择一个固定的列数,比如7列。把明文字母按行写进一个7列的表格里,就像这样:

行 列1 列2 列3 列4 列5 列6 列7
1 W E A R E D I
2 S C O V E R E
3 D F L E E A T
4 O N C E

最后一行没有填满,可以用字母X填充(或者不填,取决于约定)。这里我们暂时不填充。

现在,表格建好了,但按行读出还是原来的顺序,没什么变化。关键在于下一步:打乱列的顺序。

密钥:列的顺序

矩阵换位的“密钥”就是一个数字序列,指定了列的新顺序。比如,我们选一个密钥 4 3 1 2 5 6 7,意思就是:先读第4列,再读第3列,再读第1列,然后第2、5、6、7列。

按照这个顺序,把每一列的字母从上到下读出来:

  • 第4列:R, V, E, E → RVEE
  • 第3列:A, O, L, C → AOLC
  • 第1列:W, S, D, O → WSDO
  • 第2列:E, C, F, N → ECFN
  • 第5列:E, E, E, (空) → EEE
  • 第6列:D, R, A, (空) → DRA
  • 第7列:I, E, T, (空) → IET

把它们拼接起来:R V E E A O L C W S D O E C F N E E E D R A I E T,写成一行就是 RVEEAOLCWSDOECFNEEEDRAIET。

这就是密文。原本有规律的单词,被彻底打散成了看似随机的字母串。

解密:逆向操作

解密时需要知道两件事:列数和密钥(列的顺序)。假设我们收到了上面的密文,知道列数是7,密钥是 4 3 1 2 5 6 7。

第一步,计算矩阵的行数。密文字符数除以列数(向上取整)得到行数。这里密文有25个字母,25÷7≈3.57,所以行数是4行(最后一行不满)。

第二步,根据密钥恢复列的原始顺序。密钥告诉我们,密文的前几个字母(第4列)应该放在第4列的位置,接下来的(第3列)放在第3列的位置,以此类推。把密文按列切开,放回表格。

第三步,按行读出表格,就得到了明文。

为什么比栅栏密码强?

矩阵换位的威力在于,它不仅改变了字母的顺序,还让原本相邻的字母被分散到不同的列、不同的行。栅栏密码最多只能让相邻字母隔开几行,而矩阵换位可以把它们扔到表格的两端。

更重要的是,密钥空间大大增加了。对于7列的表格,可能的列顺序有 7! = 5040 种;对于10列,就有 3628800 种。如果不知道密钥,暴力尝试需要很久。

矩阵换位的弱点

尽管矩阵换位比栅栏密码强得多,它仍然有弱点。

首先,它保留了字母的频率特征。因为字母本身没有变,只是位置变了,所以密文的字母频率和明文完全一样。如果你知道这是一篇英文,统计每个字母出现的次数,还是能得到E、T、A等高频字母的信息——但这只能告诉你它可能是换位密码,不能直接破解。

其次,如果密钥长度固定,某些字母的相对位置会留下线索。比如,如果你知道某个单词可能出现在明文中(比如“the”),你可以尝试在密文中寻找这三个字母,看看它们之间的距离是否符合某种规律。这被称为“已知明文攻击”。

最重要的是,换位密码和替换密码可以结合起来。实际上,现代密码学中的很多算法(比如AES)就是交替进行替换和换位,让信息既改变字母本身,又打乱位置——这就是所谓的“混淆”和“扩散”。

历史的影子

矩阵换位在19世纪末到20世纪初被广泛使用,尤其是在外交和军事通信中。一战期间,德国人就曾使用过一种复杂的矩阵换位密码,称为“德国外交密码”。不过,随着频率分析和更高级的攻击方法的发展,纯换位密码也逐渐退出了历史舞台。

动手试试

  1. 用5列矩阵和密钥 3 1 4 2 5 加密:CRYPTOGRAPHYISFUN(去掉空格)。
  2. 解密下面这段密文(列数5,密钥 2 4 1 3 5):HLOOLELWRD(提示:很短,先算行数)。

如果你会Python,可以写一个简单的矩阵换位加密函数:

def columnar_transpose_encrypt(text, key):
# key是一个列表,表示列的顺序,比如 [4,3,1,2,5,6,7]
columns = len(key)
# 计算行数
rows = (len(text) + columns - 1) // columns
# 填充矩阵
matrix = [['' for _ in range(columns)] for _ in range(rows)]
index = 0
for r in range(rows):
for c in range(columns):
if index < len(text):
matrix[r][c] = text[index]
index += 1
# 按密钥顺序读取列
result = []
for k in key:
for r in range(rows):
if matrix[r][k-1]: # 如果该位置有字母
result.append(matrix[r][k-1])
return ''.join(result)

print(columnar_transpose_encrypt("WEAREDISCOVEREDFLEEATONCE", [4,3,1,2,5,6,7]))

矩阵换位告诉我们,即使不改变字母本身,仅仅改变位置,也能创造出强大的加密效果。但密码学的智慧远不止于此——在下一节,我们将回过头来,看看这些古典密码为何最终被淘汰,它们给现代密码学留下了哪些教训。