O ponto chave nesse desafio é conseguir mapear todas as letras para então conseguirmos manipulá-las somando posições na ordem alfabética. Uma forma de fazer isso é criar uma "tabela" identificando cada letra, como um array ou um objeto, mas podemos também utilizar a já existente tabela ASCII.
Para a resolução vamos utilizar a tabela ASCII para mapear as letras, pois o javascript possui métodos para lidar com isso out-of-the-box, facilitando nosso trabalho. Também vamos dividir a string em um array de caracteres com o .split() para manipulá-las melhor.
Feito isso precisamos inserir uma parte muito importante do nosso código. O número passado pode ter qualquer tamanho, mas o alfabeto é limitado, portanto precisamos que ao chegar na letra A ele volta para Z e vice-versa. Mas o nosso programa não precisa ficar dando muitas voltas pelas letras caso o número seja muito grande. Para isso podemos a matemática ao nosso favor. Com o resto da divisão por 26 (total de letras) conseguimos normalizar o número passado, deixando apenas o número exato de posições a mudar sem dar nenhuma "volta completa" por todas as letras.
function caesarCipher(str, key) { const charsArray = str.split('')
const normalizedKey = key % 26
}
Depois disso podemos iterar sobre o array de caracteres utilizando o .map() para obter os códigos de todos os caracteres atuais junto com o .charCodeAt() do próprio javascript. No caso de utilizar a tabela ASCII precisamos trabalhar com as posições de letras maiúsculas e minúsculas separadamente, pois elas ocupam posições separadas na tabela. Também devemos lidar com o caso de uma letra chegar ao começo do alfabeto (Z) e então precisar voltar ao fim (Z). Para isso podemos simplesmente somar 26 posições, pois ao subtrair será como se ela tivesse voltado para o fim do alfabeto.
function caesarCipher(str, key) {
const charsArray = str.split('')
const normalizedKey = key % 26
const codesArray = charsArray.map(char => {
const currentCode = char.charCodeAt(0)
if (currentCode - normalizedKey < 65 && currentCode >= 65 && currentCode <= 90) {
return currentCode + 26
}
if (currentCode - normalizedKey < 97 && currentCode >= 97 && currentCode <= 122) {
return currentCode + 26
}
return currentCode
})
}
Por fim agora só precisamos utilizar o String.fromCharCode do próprio javascript para obtermos a letra a partir do código atual subtraído da nossa chave normalizada. Utilizando o .map() faremos isso para todos as letras e depois apenas precisaremos unir o array em uma string.
function caesarCipher(str, key) {
const charsArray = str.split('')
const normalizedKey = key % 26
const codesArray = charsArray.map(char => {
const currentCode = char.charCodeAt(0)
if (currentCode - normalizedKey < 65 && currentCode >= 65 && currentCode <= 90) {
return currentCode + 26
}
if (currentCode - normalizedKey < 97 && currentCode >= 97 && currentCode <= 122) {
return currentCode + 26
}
return currentCode
})
return codesArray.map(code => String.fromCharCode(code - normalizedKey)).join('')
}