VigenèreCipher大部分测试都通过了编码,但是有些不起作用

时间:2019-12-13 04:26:08

标签: javascript algorithm encryption

class VigenèreCipher {
    constructor(key, abc) {
        this.encode = function (str) {
            //split the string into an array
            let arr = abc.split("");
            let keyValue = [];

            for (let i = 0; i < key.length; i++) {
                //finding the letter(key) value and push it to key value
                keyValue.push(arr.indexOf(key[i]));
            }
            let redacted = "";
            let pointer = 0;
            for (let i = 0; i < str.length; i++) {
                if (arr.includes(str[i])) {
                    let shift = arr.indexOf(str[i]) + keyValue[pointer];

                    if (shift >= 26) {
                        redacted += arr[shift - 26];
                    } else {
                        redacted += arr[shift];
                    }
                    //debugging code
                    console.log(
                        `string: ${str[i]}`,
                        `shift: ${shift - 26}`,
                        `shiftTo ${arr[shift]}`,
                        `pointer: ${pointer}`,
                        `KeyValue: ${keyValue[pointer]}`
                    );
                    pointer += 1;
                } else {
                    pointer = 0;
                    redacted += str[i];
                }

                if (pointer >= keyValue.length) {
                    pointer = 0;
                }
            }

            //console.log(keyValue);
            console.log(`redacted: ${redacted}`);
            return redacted
        };
        this.decode = function (str) {
            let arr = abc.split("");
            let keyValue = [];

            for (let i = 0; i < key.length; i++) {
                //finding the letter(key) value and push it to key value
                keyValue.push(arr.indexOf(key[i]));
            }
            let decoded = "";
            let pointer = 0;
            for (let i = 0; i < str.length; i++) {
                if (arr.includes(str[i])) {
                    let shift = arr.indexOf(str[i]) - keyValue[pointer];
                    if (shift < 0) {
                        decoded += arr[26 - Math.abs((arr.indexOf(str[i]) - keyValue[pointer]))];
                    } else {
                        decoded += arr[Math.abs((arr.indexOf(str[i]) - keyValue[pointer]))];
                    }

                    //debugging code
                    console.log(
                        `string: ${str[i]} `,
                        `shift: ${arr.indexOf(str[i]) - keyValue[pointer]} `,
                        `shiftTo ${arr[arr.indexOf(str[i]) - keyValue[pointer]]} `,
                        `pointer: ${pointer} `,
                        `KeyValue: ${keyValue[pointer]} `,
                        `arrindex: ${arr.indexOf(str[i])} `,

                    );
                    pointer += 1;
                } else {
                    pointer = 0;
                    decoded += str[i];
                }

                if (pointer >= keyValue.length) {
                    pointer = 0;
                }
            }

            //console.log(keyValue);
            console.log(`decode: ${decoded}`);
            return decoded
        };
    };
}

Vigenère密码是一种通过使用一系列不同的密码来加密字母文本的方法 基于关键字字母的凯撒密码。它是多字母替换的一种简单形式。 在凯撒密码中,字母表中的每个字母都沿一定数量的位置移动;例如,在移位3的凯撒密码中,A变成D,B变成E,Y变成B,依此类推。 Vigenère密码由多个具有不同移位值的凯撒密码组成。假设在每个字符的字符长度上重复键。请注意,某些实现仅在字符是字母的一部分时才在字符上重复键-此处不是这种情况。通过将凯撒(Caesar)移位应用于具有键在字母表中的相应索引的字符来得出移位。 / strong>

**ar abc, key;
abc = "abcdefghijklmnopqrstuvwxyz";
key = "password"
c = new VigenèreCipher(key, abc);

Test.assertEquals(c.encode('codewars'), 'rovwsoiv');
Test.assertEquals(c.decode('rovwsoiv'), 'codewars');

Test.assertEquals(c.encode('waffles'), 'laxxhsj');
Test.assertEquals(c.decode('laxxhsj'), 'waffles');

Test.assertEquals(c.encode('CODEWARS'), 'CODEWARS');
Test.assertEquals(c.decode('CODEWARS'), 'CODEWARS');**

 **Expected: 'xt\'k o vwixl qzswej!', instead got: 'xt\'h p hhaxp rihzaf!'
Expected: 'it\'s a shift cipher!', instead got: 'it\'v z gwqfp bzaeiv!'**
**Expected: 'ドオカセガヨゴザキアニ', instead got: 'ドテタヒガォゴザキノイ'
Expected: 'ドモアリガトゴザイマス', instead got: 'ドタシェガホゴザイィス'**

**The code solve most problem but won't solve those any idea whats going on or how to fix it?**

2 个答案:

答案 0 :(得分:0)

当您检测到不在字母表中的字符时,会将else中的指针重置为零。通常,只有在加密时才增加密钥中的“指针”,否则您将其保留,就不会重置它。

答案 1 :(得分:0)

帖子中给出的信息

  

... 请注意,某些实现仅在字符是字母的一部分时才在字符上重复键-此处不是这种情况。 ...

要实现此目的,您需要在处理完每个每个字符后递增指针和/或将其设置为零。您可以在循环结束前立即进行pointer的无条件更新,删除其他指针更新,例如

    ...
    pointer += 1;
    if( pointer >= keyValue.length) {
        pointer = 0
    }
} // end of for loop

或通过直接将其计算为

    pointer = (pointer + 1) % keyValue.length;

这将使代码按预期方式将"it's a shift cipher!"编码为"xt'k o vwixl qzswej!",并将结果解码回原始数据而不会出错(在encode和{{1}中都修复了指针更新之后}。)