JavaScript 实现 Playfair 与 Hill 古典密码算法

周予安
周予安
发布时间:2026-10-15 | 2人浏览过
原创

Playfair 密码基于密钥生成的 5x5 矩阵,通过同行、同列或矩形规则加密双字母组合;Hill 密码则运用线性代数中的矩阵乘法对明文进行转换。本文通过 JavaScript 代码展示这两种算法的底层逻辑与实现方式。

Playfair 密码实现

Playfair 密码(Playfair cipher)是一种多字母替换密码。它依赖一个 5x5 的正方形网格作为密码表,通常包含 26 个英文字母中除去最常见的 'Z' 后的 25 个字母(或将 I/J 合并)。加密过程需要将明文划分为双字母组,并根据字母在矩阵中的相对位置执行不同的替换规则。

第一步:构建密钥矩阵

密钥矩阵是算法的核心。编制时首先将密钥单词去除重复字母和空格,然后按顺序填入矩阵剩余位置。通常使用 A-Y 的字母序列填充未被占用的位置,J 往往与 I 共用或省略 Z。

例如,若密钥为 "crazy dog",处理后的前导字母为 C、O、H、M、T...,随后依次填入其余字母:

COHMT
RGINU
ABJPV
YEKQW
DFLSX

以下是使用 JavaScript 构建该矩阵的逻辑:


/*
 * 功能:编制 Playfair 密码表
 * 参数:keychars (已转大写、去空格、去重复的密钥字符串)
 */
function createKey(keychars) {
    // 定义基础字母表 (A-Y,排除 Z)
    var allChars = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y'];
    
    // 从基础表中移除密钥中包含的字母
    for(var i = 0; i < keychars.length; i++){
        var index = allChars.indexOf(keychars[i]);
        if (index > -1) {
            allChars.splice(index, 1);
        }
    }
    
    // 将密钥首字母逆向插入到数组头部(保持密钥字母优先且正序排列)
    for(var i = keychars.length-1; i >= 0; i--){
        allChars.unshift(keychars[i]);
    }
    
    // 将一维数组填充为 5x5 二维矩阵
    var keyMatrix = new Array(5).fill(0).map(() => new Array(5));
    for(var i = 0 ; i < 5 ; i++){
        for(var j = 0; j < 5; j++){
            keyMatrix[i][j] = allChars[i*5+j];
        }
    }
    return keyMatrix;
}

为了保证密钥字符唯一性,预处理阶段需使用去重函数:


function removeDuplicate(str){
    var result = [], tempStr = "";
    var arr = str.split('');
    for(var i = 0; i < arr.length; i++){
        var isRepeat = false;
        for(var j = 0; j < result.length; j++){
            if(arr[i] == result[j]) {
                isRepeat = true;
                break;
            }
        }
        // 仅当不是重复字符时才加入结果
        if(!isRepeat){
            result.push(arr[i]);
        }
    }
    return result.join("");
}

第二步:整理明文

加密前需对明文进行标准化:
1. 去除所有空格并将字符转为大写。
2. 按顺序将字母两两分组。如果分组出现相同字母相邻(如 LL),则在中间插入分隔符(通常为 'X')。如果最后剩单数个字母,末尾补 'X'。

第三步:加密与解密规则

根据两个字母在矩阵中的坐标,应用以下规则生成密文:

  • 同行:替换为各自右侧紧邻的字母(循环回到行首)。
  • 同列:替换为各自下方紧邻的字母(循环回到列首)。
  • 矩形:选取同一行不同列的两个点构成的矩形,替换为与这两个点同行但位于另一列角的字母(通常约定左对齐右移)。

示例演示:
明文:where there is life,there is hope.
处理后分组:wh er et he re is li fe th er ei sh op ex
依据上述矩阵,密文结果为:kt yg wo ok gy nl hj of cm yg kg lm mb wf

解密过程则是上述规则的逆向操作。完整算法逻辑运行效果如下:

Hill 密码实现

Hill 密码是一种利用矩阵论的替换密码。它将明文分为长度为 n 的向量,通过与一个 n x n 的可逆密钥矩阵相乘来生成密文向量,最后对 26 取模转换为字母。

关键步骤解析

  1. 准备字母表:使用 A-Z 的索引映射数字 0-25。
  2. 生成密钥:通常生成一个 n x n 矩阵。为保证可解性,实际应用中需验证行列式与 26 互质,但在本算法的简化版中,主要演示计算流程。

/*
 * 随机生成 3x3 密钥矩阵 (数值范围 0-25)
 */
function randomCreateKey() {
    let key = [];
    for(let i = 0; i < 3; i++) {
        key[i] = [];
        for(let j = 0; j < 3; j++) {
            key[i][j] = Math.floor(Math.random() * 26);
        }
    }
    return key;
}
  1. 矩阵运算加密: 每三个字母构成一个列向量,与 3x3 密钥矩阵做乘法,结果对 26 取模后映射回字母。

function hillEncrypt(pText, keyMatrix) {
    let chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.split('');
    let plainArr = pText.toUpperCase().replace(/[^A-Z]/g, '').split('');
    let res = "";
    
    // 每次处理 3 个字母
    let round = Math.ceil(plainArr.length / 3);
    
    for(let b = 0; b < round; b++) {
        let tempArr = [];
        let sumArr = [];
        
        // 提取当前块并转为数字索引
        for(let i = 0; i < 3; i++) {
            let charCode = plainArr[b*3 + i] || 'X'; // 不足补X
            tempArr[i] = chars.indexOf(charCode);
        }
        
        // 矩阵乘法与取模
        for(let i = 0; i < 3; i++) {
            let sum = 0;
            for(let k = 0; k < 3; k++) {
                sum += keyMatrix[i][k] * tempArr[k];
            }
            sumArr[i] = sum % 26;
        }
        
        // 还原为字母
        for(let i = 0; i < 3; i++) {
            res += chars[sumArr[i]];
        }
    }
    return res;
}

总结与优化方向

通过上述 JavaScript 代码可以看出,Playfair 和 Hill 算法在逻辑上是纯粹的规则应用和数学计算。目前的实现存在以下几点值得优化的地方:

  • 耦合度问题:代码偏向面向过程,函数间变量传递较多,适合初学者理解原理,但难以复用。
  • 性能考量:过多的嵌套循环在处理长文本时会降低效率,可利用更高级的数据结构或位运算优化。
  • 健壮性增强:原始输入未充分处理非字母字符;在 Hill 密码中应添加校验机制,确保密钥矩阵可逆,否则解密将无法完成。
以上就是用 JavaScript 实现 Playfair 与 Hill 古典密码算法的详细内容,更多关于信息安全与前端算法的资料请关注本站其它相关文章!
相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表