Skip to content

Commit 8a76e2c

Browse files
authored
Refactor keyFinder: optimize Caesar cipher, remove DOM dependency
1 parent 08d8c6b commit 8a76e2c

File tree

1 file changed

+38
-103
lines changed

1 file changed

+38
-103
lines changed

Ciphers/KeyFinder.js

Lines changed: 38 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
/**
2-
* Find and retrieve the encryption key automatically.
2+
* Find and retrieve the Caesar cipher encryption key automatically.
33
* @param {string} str - The input encrypted string.
4-
* @returns {number} - The encryption key found, or 0 if not found.
4+
* @returns {number|null} - The encryption key found, or null if not found.
55
*/
66
function keyFinder(str) {
7-
// str is used to get the input of encrypted string
87
const wordBank = [
98
'I ',
109
'You ',
@@ -30,126 +29,62 @@ function keyFinder(str) {
3029
'May ',
3130
' be ',
3231
'Be '
33-
]
34-
const inStr = str.toString() // convert the input to String
35-
let outStr = '' // store the output value
36-
let outStrElement = '' // temporary store the word inside the outStr, it is used for comparison
32+
];
33+
34+
const inStr = String(str);
35+
3736
for (let k = 0; k < 26; k++) {
38-
// try the number of key shifted, the sum of character from a-z or A-Z is 26
39-
outStr = caesarCipherEncodeAndDecodeEngine(inStr, k) // use the encryption engine to decrypt the input string
37+
const outStr = caesarCipherEncodeAndDecodeEngine(inStr, k);
4038

41-
// loop through the whole input string
4239
for (let s = 0; s < outStr.length; s++) {
4340
for (let i = 0; i < wordBank.length; i++) {
44-
// initialize the outStrElement which is a temp output string for comparison,
45-
// use a loop to find the next digit of wordBank element and compare with outStr's digit
46-
for (let w = 0; w < wordBank[i].length; w++) {
47-
outStrElement += outStr[s + w]
48-
}
49-
// this part need to be optimize with the calculation of the number of occurrence of word's probabilities
50-
// linked list will be used in the next stage of development to calculate the number of occurrence of the key
51-
if (wordBank[i] === outStrElement) {
52-
return k // return the key number if founded
41+
const word = wordBank[i];
42+
const segment = outStr.slice(s, s + word.length);
43+
44+
if (segment === word) {
45+
return k; // Found the key
5346
}
54-
outStrElement = '' // reset the temp word
55-
} // end for (let i=0; i < wordBank.length; i++)
47+
}
5648
}
5749
}
58-
return 0 // return 0 if found nothing
50+
51+
return null; // Key not found
5952
}
6053

6154
/**
62-
* This sub-function is used to assist the keyFinder in finding the key.
55+
* Caesar cipher encode/decode engine.
6356
* @param {string} inStr - The input string.
64-
* @param {number} numShifted - The number of characters to shift in the Caesar cipher.
65-
* @returns {string} - The decrypted string.
57+
* @param {number} shiftNum - Number of characters to shift (0-25).
58+
* @returns {string} - The shifted string.
6659
*/
67-
function caesarCipherEncodeAndDecodeEngine(inStr, numShifted) {
68-
const shiftNum = numShifted
69-
let charCode = 0
70-
let shiftedCharCode = 0
71-
let result = 0
72-
60+
function caesarCipherEncodeAndDecodeEngine(inStr, shiftNum) {
7361
return inStr
7462
.split('')
7563
.map((char) => {
76-
charCode = char.charCodeAt()
77-
shiftedCharCode = charCode + shiftNum
78-
result = charCode
79-
80-
if (charCode >= 48 && charCode <= 57) {
81-
if (shiftedCharCode < 48) {
82-
let diff = Math.abs(48 - 1 - shiftedCharCode) % 10
83-
84-
while (diff >= 10) {
85-
diff = diff % 10
86-
}
87-
document.getElementById('diffID').innerHTML = diff
88-
89-
shiftedCharCode = 57 - diff
90-
91-
result = shiftedCharCode
92-
} else if (shiftedCharCode >= 48 && shiftedCharCode <= 57) {
93-
result = shiftedCharCode
94-
} else if (shiftedCharCode > 57) {
95-
let diff = Math.abs(57 + 1 - shiftedCharCode) % 10
64+
const code = char.charCodeAt(0);
9665

97-
while (diff >= 10) {
98-
diff = diff % 10
99-
}
100-
document.getElementById('diffID').innerHTML = diff
101-
102-
shiftedCharCode = 48 + diff
103-
104-
result = shiftedCharCode
105-
}
106-
} else if (charCode >= 65 && charCode <= 90) {
107-
if (shiftedCharCode <= 64) {
108-
let diff = Math.abs(65 - 1 - shiftedCharCode) % 26
109-
110-
while (diff % 26 >= 26) {
111-
diff = diff % 26
112-
}
113-
shiftedCharCode = 90 - diff
114-
result = shiftedCharCode
115-
} else if (shiftedCharCode >= 65 && shiftedCharCode <= 90) {
116-
result = shiftedCharCode
117-
} else if (shiftedCharCode > 90) {
118-
let diff = Math.abs(shiftedCharCode - 1 - 90) % 26
119-
120-
while (diff % 26 >= 26) {
121-
diff = diff % 26
122-
}
123-
shiftedCharCode = 65 + diff
124-
result = shiftedCharCode
125-
}
126-
} else if (charCode >= 97 && charCode <= 122) {
127-
if (shiftedCharCode <= 96) {
128-
let diff = Math.abs(97 - 1 - shiftedCharCode) % 26
66+
// Uppercase A-Z
67+
if (code >= 65 && code <= 90) {
68+
return String.fromCharCode(((code - 65 + shiftNum) % 26) + 65);
69+
}
12970

130-
while (diff % 26 >= 26) {
131-
diff = diff % 26
132-
}
133-
shiftedCharCode = 122 - diff
134-
result = shiftedCharCode
135-
} else if (shiftedCharCode >= 97 && shiftedCharCode <= 122) {
136-
result = shiftedCharCode
137-
} else if (shiftedCharCode > 122) {
138-
let diff = Math.abs(shiftedCharCode - 1 - 122) % 26
71+
// Lowercase a-z
72+
if (code >= 97 && code <= 122) {
73+
return String.fromCharCode(((code - 97 + shiftNum) % 26) + 97);
74+
}
13975

140-
while (diff % 26 >= 26) {
141-
diff = diff % 26
142-
}
143-
shiftedCharCode = 97 + diff
144-
result = shiftedCharCode
145-
}
76+
// Digits 0-9
77+
if (code >= 48 && code <= 57) {
78+
return String.fromCharCode(((code - 48 + shiftNum) % 10) + 48);
14679
}
147-
return String.fromCharCode(parseInt(result))
80+
81+
// Non-alphabetic characters remain unchanged
82+
return char;
14883
})
149-
.join('')
84+
.join('');
15085
}
15186

152-
export { keyFinder }
87+
export { keyFinder };
15388

154-
// > keyFinder('test')
155-
// 0
89+
// Example usage:
90+
// console.log(keyFinder("Uifsf jt b tfdsfu nfttbhf")); // Should return 1

0 commit comments

Comments
 (0)