El cifrado César, en criptografía, es un tipo de cifrado de sustitución en el que cada letra del mensaje original es reemplazada por otra letra que se encuentra un número fijo de posiciones más adelante en el alfabeto. Es posible que recordéis que ya hicimos en el pasado un ejercicio similar a este, usando el sistema de cifrado Rot13, que es otra forma de cifrado de sustitución muy similar. El cifrado César debe su nombre a Julio César, ya que cifraba sus mensajes militares usando un desplazamiento de tres posiciones, o al menos eso contaba Suetonio.
Usando el ejemplo de César con un desplazamiento de 3 posiciones, la letra A se convertiría en D, la letra B se convertiría en E, y así sucesivamente. Como es evidente, llegaría un punto en el que nos quedaríamos sin letras, por lo que el alfabeto se recorre de forma circular, volviendo a la A cuando pasemos de la Z.
Es un método simple e ingenioso, aunque hoy por hoy no muy seguro pues es bastante fácil de descubrir y de descifrar. ¿Podríamos hacer una función de Javascript que utilice este método de cifrado? Desde luego, haremos una pensada para una codificación de caracteres UTF-16 y que en lugar de tener un desplazamiento fijo como en Rot13 (que son siempre 13 caracteres), recibirá un parámetro con el desplazamiento que queremos aplicar:
function caesar(txt, desp) {
var respuesta = "";
//bucle for que recorre la cadena y sustituye cada caracter.
for (var i = 0; i < txt.length; i++) {
var caracter = txt[i];
// Verifica si el caracter es una letra del alfabeto
if (/[a-zA-Z]/.test(caracter)) {
// sumamos al código del caracter el desplazamiento
var codigo = txt.charCodeAt(i) + desp;
// alfabeto circular: si nos pasamos de la z retrocedemos 26 caracteres
// los 26 del alfabeto anglosajón, jo tenemos soporte para ñ ni acentos.
if (/[a-z]/.test(caracter) && codigo > 122) {
codigo -= 26;
} else if (/[A-Z]/.test(caracter) && codigo > 90) {
codigo -= 26;
} else if (codigo < 0) {
codigo += 26;
}
caracter = String.fromCharCode(codigo);
}
respuesta += caracter;
}
return respuesta;
}