From 8a76e2c3f1be17b73e9d934200094a3eee7e5189 Mon Sep 17 00:00:00 2001 From: Sanoj Ahamed Date: Mon, 13 Oct 2025 23:02:49 +0530 Subject: [PATCH] Refactor keyFinder: optimize Caesar cipher, remove DOM dependency --- Ciphers/KeyFinder.js | 141 ++++++++++++------------------------------- 1 file changed, 38 insertions(+), 103 deletions(-) diff --git a/Ciphers/KeyFinder.js b/Ciphers/KeyFinder.js index 0b799e7496..c352dd03aa 100644 --- a/Ciphers/KeyFinder.js +++ b/Ciphers/KeyFinder.js @@ -1,10 +1,9 @@ /** - * Find and retrieve the encryption key automatically. + * Find and retrieve the Caesar cipher encryption key automatically. * @param {string} str - The input encrypted string. - * @returns {number} - The encryption key found, or 0 if not found. + * @returns {number|null} - The encryption key found, or null if not found. */ function keyFinder(str) { - // str is used to get the input of encrypted string const wordBank = [ 'I ', 'You ', @@ -30,126 +29,62 @@ function keyFinder(str) { 'May ', ' be ', 'Be ' - ] - const inStr = str.toString() // convert the input to String - let outStr = '' // store the output value - let outStrElement = '' // temporary store the word inside the outStr, it is used for comparison + ]; + + const inStr = String(str); + for (let k = 0; k < 26; k++) { - // try the number of key shifted, the sum of character from a-z or A-Z is 26 - outStr = caesarCipherEncodeAndDecodeEngine(inStr, k) // use the encryption engine to decrypt the input string + const outStr = caesarCipherEncodeAndDecodeEngine(inStr, k); - // loop through the whole input string for (let s = 0; s < outStr.length; s++) { for (let i = 0; i < wordBank.length; i++) { - // initialize the outStrElement which is a temp output string for comparison, - // use a loop to find the next digit of wordBank element and compare with outStr's digit - for (let w = 0; w < wordBank[i].length; w++) { - outStrElement += outStr[s + w] - } - // this part need to be optimize with the calculation of the number of occurrence of word's probabilities - // linked list will be used in the next stage of development to calculate the number of occurrence of the key - if (wordBank[i] === outStrElement) { - return k // return the key number if founded + const word = wordBank[i]; + const segment = outStr.slice(s, s + word.length); + + if (segment === word) { + return k; // Found the key } - outStrElement = '' // reset the temp word - } // end for (let i=0; i < wordBank.length; i++) + } } } - return 0 // return 0 if found nothing + + return null; // Key not found } /** - * This sub-function is used to assist the keyFinder in finding the key. + * Caesar cipher encode/decode engine. * @param {string} inStr - The input string. - * @param {number} numShifted - The number of characters to shift in the Caesar cipher. - * @returns {string} - The decrypted string. + * @param {number} shiftNum - Number of characters to shift (0-25). + * @returns {string} - The shifted string. */ -function caesarCipherEncodeAndDecodeEngine(inStr, numShifted) { - const shiftNum = numShifted - let charCode = 0 - let shiftedCharCode = 0 - let result = 0 - +function caesarCipherEncodeAndDecodeEngine(inStr, shiftNum) { return inStr .split('') .map((char) => { - charCode = char.charCodeAt() - shiftedCharCode = charCode + shiftNum - result = charCode - - if (charCode >= 48 && charCode <= 57) { - if (shiftedCharCode < 48) { - let diff = Math.abs(48 - 1 - shiftedCharCode) % 10 - - while (diff >= 10) { - diff = diff % 10 - } - document.getElementById('diffID').innerHTML = diff - - shiftedCharCode = 57 - diff - - result = shiftedCharCode - } else if (shiftedCharCode >= 48 && shiftedCharCode <= 57) { - result = shiftedCharCode - } else if (shiftedCharCode > 57) { - let diff = Math.abs(57 + 1 - shiftedCharCode) % 10 + const code = char.charCodeAt(0); - while (diff >= 10) { - diff = diff % 10 - } - document.getElementById('diffID').innerHTML = diff - - shiftedCharCode = 48 + diff - - result = shiftedCharCode - } - } else if (charCode >= 65 && charCode <= 90) { - if (shiftedCharCode <= 64) { - let diff = Math.abs(65 - 1 - shiftedCharCode) % 26 - - while (diff % 26 >= 26) { - diff = diff % 26 - } - shiftedCharCode = 90 - diff - result = shiftedCharCode - } else if (shiftedCharCode >= 65 && shiftedCharCode <= 90) { - result = shiftedCharCode - } else if (shiftedCharCode > 90) { - let diff = Math.abs(shiftedCharCode - 1 - 90) % 26 - - while (diff % 26 >= 26) { - diff = diff % 26 - } - shiftedCharCode = 65 + diff - result = shiftedCharCode - } - } else if (charCode >= 97 && charCode <= 122) { - if (shiftedCharCode <= 96) { - let diff = Math.abs(97 - 1 - shiftedCharCode) % 26 + // Uppercase A-Z + if (code >= 65 && code <= 90) { + return String.fromCharCode(((code - 65 + shiftNum) % 26) + 65); + } - while (diff % 26 >= 26) { - diff = diff % 26 - } - shiftedCharCode = 122 - diff - result = shiftedCharCode - } else if (shiftedCharCode >= 97 && shiftedCharCode <= 122) { - result = shiftedCharCode - } else if (shiftedCharCode > 122) { - let diff = Math.abs(shiftedCharCode - 1 - 122) % 26 + // Lowercase a-z + if (code >= 97 && code <= 122) { + return String.fromCharCode(((code - 97 + shiftNum) % 26) + 97); + } - while (diff % 26 >= 26) { - diff = diff % 26 - } - shiftedCharCode = 97 + diff - result = shiftedCharCode - } + // Digits 0-9 + if (code >= 48 && code <= 57) { + return String.fromCharCode(((code - 48 + shiftNum) % 10) + 48); } - return String.fromCharCode(parseInt(result)) + + // Non-alphabetic characters remain unchanged + return char; }) - .join('') + .join(''); } -export { keyFinder } +export { keyFinder }; -// > keyFinder('test') -// 0 +// Example usage: +// console.log(keyFinder("Uifsf jt b tfdsfu nfttbhf")); // Should return 1