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?**
答案 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}中都修复了指针更新之后}。)