Julio César 007
CriptografíaCifrado César
Nunca hasta ahora habíamos recibido un mensaje de una época tan remota: del siglo I antes de Cristo. ¡Como lo lees! Desde la mismísima Roma, Julio César nos mandó un mensaje escrito en un pergamino que recibimos esta misma mañana.
Al parecer, además de emperador y militar, Julio César hizo sus pinitos con la criptografía. De hecho, ha inventado un sistema de cifrado bastante rudimentario que, fíjate por dónde, ha llegado hasta nuestros días (dos milenios después) bautizado como Cifrado César.
Pues bien, necesita que le hagamos un codificador / decodificador de mensajes porque dice que lo de hacerlo a mano le parece un rollo. Así nos contaba:
Queridos amigos:
Soy Cayo Julio César, emperador romano; pero me podéis llamar César. Desde hace tiempo envío mis mensajes sobre estrategia militar con un método que consiste en lo siguiente: escribo una frase y luego sustituyo cada letra por la letra correspondiente tres espacios más a la derecha. Por ejemplo, ADA lo sustituiría por DGD; y EDU por HGX. Pero cuando los mensajes son largos la codificación es un rollo, y además, hacerlo siempre con un desplazamiento de 3 espacios es poco seguro. Necesito un codificador y decodificador que, a partir de un mensaje y un número de desplazamiento (positivo o negativo) me devuelva el mensaje codificado o decodificado respectivamente. Solo trabajaré con letras mayúsculas, y los símbolos, números y espacios no necesito codificarlos ni decodificarlos. ¿Podríais ayudarme?
¡Bueno! No esperábamos menos de Julio César, que contribuyó a la historia de la criptografía con su sistema de cifrado. Si quieres leer más, te dejo el enlace a la Wikipedia sobre el Cifrado César donde se explica el método y la historia.
Edu, una vez más, contribuyó a que me planteara ciertas cuestiones:
Necesitaremos dos campos: uno para el mensaje y otro para el desplazamiento; y dos botones, para codificar y decodificar, ¿verdad? ¿Vas a hacerlo con un bucle o utilizando lambdas y funciones flecha? ¿Vas a mezclar todo o a crear un método de codificación y otro de decodificación? A este señor se lo cargaron en alguna peli, ¿no?
No lo tenía claro aún, pero alguna de las preguntas de Edu me hicieron plantearme el problema dos veces.
¿Tú cómo lo harías? ¡Deja tus ideas en los comentarios!
Y si quieres compartir código, te recomiendo que utilices alguna herramienta online de testing de código como Codepen, JSFiddle, PlayCode, etc. o repositorios como GitHub, GitLab, BitBucket…
FEDERICO MACÍAS says
Wow. Está interesantísimo el reto. Además nos empezamos a meter en el ámbito de la criptografía. Genial el reto, como siempre huelga decir que intentaré hacerlo, aunque seguramente me tope con nuevos errores.
Muchísimas gracias, Ada.
Ada Lovecode says
¡Lo importante es intentarlo, Federico! Recuerda que SIEMPRE aprendes algo en tus intentos, así que sigue así… y verás tu progreso poco a poco 🙂
Rafael García says
Pues ahí nos has pillado. Se me ocurre a bote pronto una forma un poco cutre.
Tendría dos arrays uno desde la a-z y luego otro comenzando por la c y terminando en b.
De tal forma que recorramos las palabras del mensaje carácter a carácter (charAt) y buscando dicha letra en el array de la a-z para obtener su posición y con ella buscar mediante ese índice la letra en el segundo array.
El el caso de no encontrarlo (porque el carácter a evaluar sea un espacio en blanco o un número) pondría el carácter tal cual.
No sé si me he explicado, es la forma que se me ha ocurrido sin llegar a meternos en temas de jugar con caracteres ASCII.
Un saludo y gracias por hacernos pensar tanto;)
José Julio says
let alfabeto = (“ABCDEFGHIJKLMNÑOPQRSTUVWXYZ”);
function codificar(texto, desplazamiento=0){
// todo en mayúscula
texto = texto.toUpperCase();
// elimino espacios
texto = texto.replace(/ /g,””);
let texto_codificado=””;
let array_texto = texto.split(“”);
let posicion = 0;
for(let index = 0; index < array_texto.length; index++){
// si la letra esta incluida en alfabeto
if(alfabeto.includes(array_texto[index])){
// aritmetica modular. 27 porque hay 27 letras.
posicion = (alfabeto.indexOf(array_texto[index]) + desplazamiento) % 27;
if(posicion < 0){
posicion = 27 + posicion;
}
texto_codificado += alfabeto.charAt(posicion);
}
}
return texto_codificado;
}
function iniciar(){
texto = document.getElementById("texto").value;
desplazamiento = parseInt(document.getElementById("desplazamiento").value);
desplazamiento = isNaN(desplazamiento) ? 0 : desplazamiento;
document.getElementById("texto_codificado").value = codificar(texto, desplazamiento);
}
function borrar(){
document.getElementById("texto").value="";
document.getElementById("texto_codificado").value="";
document.getElementById("desplazamiento").value="";
}
Rafael García says
Ah cierto, llevas razón debe funcionar para cualquier desplazamiento no sólo 3 como había entendido yo.
Sorry
José Julio says
No me deja subir el HTML. En el código JavaScript “texto” y “texto_codificado” son textarea. “desplazamiento” es un input tipo text. Hay dos botones: “codificar” y “borrar”. “codificar” invoca a la función “inicio()” de JavaScript. “borrar” es fácil de adivinar qué es lo que hace.
Ada Lovecode says
¡Bueno, la que habéis liado en un momento!
Eso es, Rafa, en principio valdría cualquier desplazamiento. Yo creo que te has liado con el cifrado que utilizaba en su día Julio César. Pero ahora podríamos elegir cualquiera. De hecho, el ROT-13 es uno de los más comunes (que es un César de desplazamiento 13).
Por otro lado, José Julio, ¡muy buen planteamiento! Es muy parecido a lo que tengo hilado. Eso sí, ¿valoras que introduzca un número negativo? Os pondré una forma normal y otra, para no variar, con lambdas… 😉
¡Buen trabajo!
Juan says
window.onload = cargaLista;
const ABECEDARIO = [“a”,”b”,”c”,”d”,”e”,”f”,”g”,”h”,”i”,”j”,”k”,”l”,”m”,”n”,”ñ”,”o”,”p”,”q”,”r”,”s”,”t”,”u”,”v”,”w”,”x”,”y”,”z”];
let posicionLetra = document.getElementById(“textoDelArea”);
let ingreso = document.getElementById(“convertido”);
let cont1 = false;
let valorDeLlave;
let ban1 = false;
let ban2 = false;
let conversion;
let cont = 0;
let cuerpo;
let valor;
let btn1;
let btn2;
let n;
function cargaLista()
{
cuerpo = document.getElementById(“cuerpo”);
document.getElementById(“borrar”).addEventListener(“click”,borrarValores);
btn1 = document.getElementById(“encriptar”).addEventListener(“click”,validacion);
btn2 = document.getElementById(“desencriptar”).addEventListener(“click”,desencriptarUsandoLlave);
}
function validacion()
{
valorDeLlave = document.getElementById(“llaveDeCifrado”);
switch(valorDeLlave.value)
{
case “”:
case “0”:
alert(“El valor ingresado en donde se ingresa la llave es incorrecto”);
valorDeLlave.style = “background-color: red”;
valorDeLlave.style.color = “white”;
break;
default:
valorDeLlave.style = “background-color: white”;
valorDeLlave.style.color = “black”;
ban1 = true;
break;
}
switch(posicionLetra.value)
{
case “”:
alert(“El valor ingresado en donde se ingresa el texto es incorrecto”);
posicionLetra.style = “background-color: red; width: 500px; height: 100px;”;
posicionLetra.style.color = “white”;
break;
default:
posicionLetra.style = “background-color: white; width: 500px; height: 100px;”;
posicionLetra.style.color = “black”;
ban2 = true;
if(ban1 && cont1)
{
ban2 = false;
}
break;
}
if(ban1 && ban2)
{
ban1 = false;
ban2 = false;
conversionInstantanea();
}
else
{
cont1 = false;
ban1 = false;
desencriptadoInstantaneo();
}
}
function conversionInstantanea()
{
for(let i = 0; i < posicionLetra.value.length; i++)
{
n = posicionLetra.value.charAt(i);
conversion = (ABECEDARIO.indexOf(n) + parseInt(valorDeLlave.value) ) % 27;
valor = ABECEDARIO[conversion];
ingreso.value += valor;
}
}
function borrarValores()
{
posicionLetra.value = "";
ingreso.value = "";
}
function desencriptarUsandoLlave()
{
cont1 = true;
validacion();
}
function desencriptadoInstantaneo()
{
for(let i = 0; i < posicionLetra.value.length; i++)
{
n = posicionLetra.value.charAt(i);
conversion = (ABECEDARIO.indexOf(n) – parseInt(valorDeLlave.value) ) % 27;
if(conversion < 0)
{
conversion *= -1;
conversion = 27 – conversion;
}
valor = ABECEDARIO[conversion];
ingreso.value += valor;
}
}
Ada Lovecode says
¡Juan, esos nombres de variables! Jejejeje. Bueno, ya te lo comenté por correo… ¿has visto la solución? ¿cómo lo ves?
Ada Lovecode says
¡Cierto! 🙂
Dani Armando says
Me parece que he llegado un poco tarde, pero quise hacerlo por mi cuenta, espero que les guste el spaghetti. https://github.com/daniarmandorsweb/julio-cesar-007.git
didacticode says
¡Uau, Dani! ¡Pues sí que te lo has trabajado! ¿Eh? ¡Muy bien hecho! Tienes un código muy reutilizable y muy bien modularizado. ¡Enhorabuena!