/** * Find and retrieve the encryption key automatically. * @param {string} str - The input encrypted string. * @returns {number} - The encryption key found, or 0 if not found. */ function keyFinder(str) { // str is used to get the input of encrypted string const wordBank = [ 'I ', 'You ', 'We ', 'They ', 'He ', 'She ', 'It ', ' the ', 'The ', ' of ', ' is ', 'Is ', ' am ', 'Am ', ' are ', 'Are ', ' have ', 'Have ', ' has ', 'Has ', ' may ', '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 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 // 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 } outStrElement = '' // reset the temp word } // end for ( let i=0; i < wordBank.length; i++) } } return 0 // return 0 if found nothing } /** * This sub-function is used to assist the keyFinder in finding the key. * @param {string} inStr - The input string. * @param {number} numShifted - The number of characters to shift in the Caesar cipher. * @returns {string} - The decrypted string. */ function caesarCipherEncodeAndDecodeEngine(inStr, numShifted) { const shiftNum = numShifted let charCode = 0 let shiftedCharCode = 0 let result = 0 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 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 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 while (diff % 26 >= 26) { diff = diff % 26 } shiftedCharCode = 97 + diff result = shiftedCharCode } } return String.fromCharCode(parseInt(result)) }) .join('') } export { keyFinder } // > keyFinder('test') // 0