維吉尼亞(Vigenere)密碼算法描述與實現

維吉尼亞密碼

QUOTE 《密碼編碼學與網絡安全——原理與實踐(第五版)》

多表代替密碼中最著名和最簡單的是 Vigenere 密碼。它的代替規則集由 26 個 Caesar 密碼的代替表組成,其中每一個代替表是對明文字母表移位 0 到 25 次後得到的代替單表。

算法描述

  • 明文:P=p1p2...pn{\rm P = p_1 p_2 ... p_n}

  • 密鑰:K=k1k2...km{\rm K = k_1 k_2 ... k_m}

  • 密文:C=c1c2...cn{\rm C = c_1 c_2 ... c_n}

  • 加密:ci=(pi+kimodm)mod26{\rm c_i = (p_i + k_{i \, mod \, m}) \, mod \, 26}

  • 解密:pi=(cikimodm)mod26{\rm p_i = (c_i - k_{i \, mod \, m}) \, mod \, 26}

算法實現

加密:

function encodeWithVigenere(pStr, kStr) {
    const p = pStr.replace(/\s/g, '').toLowerCase().split('').map(piStr => piStr.charCodeAt() - 97);
    const k = kStr.replace(/\s/g, '').toLowerCase().split('').map(kiStr => kiStr.charCodeAt() - 97);
    const m = k.length;

    const c = [];
    for (let i = 0; i < p.length; i++) {
        let ci = (p[i] + k[i % m]) % 26;
        c.push(ci);
    }

    return c.map(ci => String.fromCharCode(ci + 97)).join('');
}

解密:

function decodeWithVigenere(cStr, kStr) {
    const c = cStr.replace(/\s/g, '').toLowerCase().split('').map(ciStr => ciStr.charCodeAt() - 97);
    const k = kStr.replace(/\s/g, '').toLowerCase().split('').map(kiStr => kiStr.charCodeAt() - 97);
    const m = k.length;

    const p = [];
    for (let i = 0; i < c.length; i++) {
        let temp = (c[i] - k[i % m]);
        let pi = ((temp < 0 ? temp + 26 : temp)) % 26;
        p.push(pi);
    }

    return p.map(pi => String.fromCharCode(pi + 97)).join('');
}

測試:

let cStr = encodeWithVigenere('we are discovered save yourself', 'deceptive');
console.log('p =', cStr);
let pStr = decodeWithVigenere(cStr, 'deceptive');
console.log('c =', pStr);
$ node a.js
p = zicvtwqngrzgvtwavzhcqyglmgj
c = wearediscoveredsaveyourself
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章