Created
September 7, 2022 15:01
-
-
Save ChlorUpload/559c4d52ce0f32ccf9a366f847bc54c5 to your computer and use it in GitHub Desktop.
vigenere cipher
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* alphabet order | |
*/ | |
const alphabet = "abcdefghijklmnopqrstuvwxyz"; | |
const alphabetOrderMap = new Map([...alphabet].map((c, i) => [c, i])); | |
const orderAlphabetMap = new Map([...alphabet].map((c, i) => [i, c])); | |
/** | |
* utils | |
*/ | |
function repeat(str: string, length: number): string { | |
if (str.length <= 0 || length < 0) throw new Error("invalid argument length"); | |
const numStrRepeat = Math.floor(length / str.length); | |
const numLeft = length % str.length; | |
let ret = str.repeat(numStrRepeat); | |
ret += str.slice(0, numLeft); | |
return ret; | |
} | |
/** | |
* tests | |
*/ | |
function repeatTest() { | |
assertEq(repeat("abcde", 0), ""); | |
assertEq(repeat("abcde", 3), "abc"); | |
assertEq(repeat("abcde", 5), "abcde"); | |
assertEq(repeat("abcde", 9), "abcdeabcd"); | |
assertEq(repeat("abcde", 13), "abcdeabcdeabc"); | |
} | |
function integrateTest() { | |
assertEq(vigenereCipher("attack at dawn", "lemon"), "lxfopv mh oeib"); | |
} | |
/** | |
* test utils | |
*/ | |
function assertEq<T>(x: T, y: T) { | |
if (x !== y) throw new Error(`${x} is not equal to ${y}`); | |
} | |
function runTests() { | |
repeatTest(); | |
console.log("repeatTest ok"); | |
integrateTest(); | |
console.log("integrateTest ok"); | |
} | |
runTests(); | |
/** | |
* code | |
*/ | |
function vigenereCipher(originalStr: string, key: string): string { | |
const expandedKey = repeat(key, originalStr.length); | |
let ret = ""; | |
for (let i = 0; i < expandedKey.length; i++) { | |
if (!alphabetOrderMap.has(originalStr[i])) { | |
ret += originalStr[i]; | |
continue; | |
} | |
const charOrder = alphabetOrderMap.get(originalStr[i])!; | |
const keyCharOrder = alphabetOrderMap.get(expandedKey[i])!; | |
const destOrder = (charOrder + keyCharOrder) % 26; | |
const destChar = orderAlphabetMap.get(destOrder); | |
ret += destChar; | |
} | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment