Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
141 changes: 38 additions & 103 deletions Ciphers/KeyFinder.js
Original file line number Diff line number Diff line change
@@ -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 ',
Expand All @@ -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
Loading