1. 介绍

本文将深入探讨Vigenère密码的工作原理,并展示如何在Java中实现其加密与解密过程。作为经典凯撒密码的升级版,Vigenère密码通过动态移位机制显著提升了安全性。

2. 什么是Vigenère密码?

Vigenère密码本质上是凯撒密码的增强版,核心差异在于每个字母的移位量不同。

在凯撒密码中,所有字母按固定值移位(例如统一右移3位)。比如字符串 "BAELDUNG" 会变成 "EDHOGXQJ"

凯撒密码示例

解密只需反向移位相同位数即可。

Vigenère密码的突破点在于:每个字母使用不同的移位量。 这需要通过密钥字符串来定义移位规则——密钥中每个字母对应其在字母表中的位置作为移位值。例如密钥 "HELLO" 表示:

  • 首字母移位8位(H是第8个字母)
  • 次字母移位5位(E是第5个字母)
  • 以此类推

用此密钥加密 "BAELDUNG" 会得到 "JFQXSCSS"

Vigenère密码示例

3. 实现Vigenère密码

理解原理后,我们直接用Java实现加密算法。 先构建基础框架:

public String encode(String input, String key) {
    String result = "";

    for (char c : input.toCharArray()) {
        result += c;
    }

    return result;
}

当前代码仅原样返回输入,接下来添加密钥处理逻辑。引入密钥位置计数器,并实现循环取用:

int keyPosition = 0;
for (char c : input.toCharArray()) {
    char k = key.charAt(keyPosition % key.length());
    keyPosition++;
    .....
}

关键点解析:

  • keyPosition % key.length() 实现密钥循环使用
  • 每次迭代后递增密钥位置

最后实现字母移位逻辑:

String characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
.....
int charIndex = characters.indexOf(c);
int keyIndex = characters.indexOf(k);

int newCharIndex = (charIndex + keyIndex + 1) % characters.length();
c = characters.charAt(newCharIndex);

⚠️ 注意三个细节:

  1. +1 使密钥字母从1开始计数(A=1而非0)
  2. 取模运算处理字母表循环
  3. 仅当输入字符在支持列表内时才处理

完善后的条件判断:

if (charIndex >= 0) {
    if (keyIndex >= 0) {
        int newCharIndex = (charIndex + keyIndex + 1) % characters.length();
        c = characters.charAt(newCharIndex);
    }
    keyPosition++;
}

3.1. 演示案例

通过实际案例验证算法有效性。 用密钥 "BAELDUNG" 加密字符串 "VIGENERE CIPHER IN JAVA"

初始 keyPosition = 0,首轮迭代:

  • 输入字符:'V'
  • 密钥字符:'B'
  • 字符索引:21
  • 密钥索引:1
  • 新索引:(21 + 1 + 1) % 26 = 23 → 'X'

第二轮迭代:

  • keyPosition = 1
  • 输入字符:'I'
  • 密钥字符:'A'
  • 字符索引:8
  • 密钥索引:0
  • 新索引:(8 + 0 + 1) % 26 = 9 → 'J'

跳到第9个字符(空格):

  • keyPosition = 9(已超过密钥长度,循环到开头)
  • 输入字符:' '(不在支持列表)
  • 密钥字符:'B'
  • 字符索引:-1 → 跳过处理

完整加密结果:"XJLQRZFL EJUTIM WU LBAM"

4. 解密Vigenère密码

解密算法与加密高度相似,核心差异在于移位方向相反。 需将加法改为减法,并手动处理负数取模:

int newCharIndex = charIndex - keyIndex - 1;
if (newCharIndex < 0) {
    newCharIndex = characters.length() + newCharIndex;
}

验证解密:用密钥 "BAELDUNG" 解密 "XJLQRZFL EJUTIM WU LBAM"

首轮迭代:

  • 输入字符:'X'(索引23)
  • 密钥字符:'B'(索引1)
  • 新索引:23 - 1 - 1 = 21 → 'V'

完整解密结果:"VIGENERE CIPHER IN JAVA"

5. Vigenère密码的调整

掌握基础实现后,可尝试以下增强方案(需同步修改加密/解密逻辑):

扩展字符集

  • 添加带重音符号的字母、空格、标点等
  • 示例:添加空格后,"VIGENERE CIPHER IN JAVA" 加密结果变为 "XJLQRZELBDNALZEGKOEVEPO"

打乱字符映射顺序

  • 破坏字母表顺序提升安全性
  • 示例:使用 "JQFVHPWORZSLNMKYCGBUXIEDTA" 替代标准字母表
  • 相同输入 "BAELDUNG" + 密钥 "HELLO" → 输出变为 "DERDPTZV"

⚠️ 高级变体

  • 交换加密/解密方向(如Variant Beaufort密码)
  • 此类调整会偏离标准Vigenère密码,但能显著提升安全性

所有修改必须确保加密端与解密端完全一致,否则将导致解密失败。这种自定义机制能有效抵御未知调整的攻击。

6. 总结

本文系统介绍了Vigenère密码的原理与Java实现,包括:

  • 动态移位的核心机制
  • 完整的加密/解密代码实现
  • 实际案例验证
  • 安全性增强方案

建议读者尝试实现文中的字符集扩展或映射顺序调整,亲手体验密码学优化的实践过程。完整代码示例可在GitHub仓库获取。