# Estructuras de repetición - Cifrado Vigenere ![main1.png](images/main1.png) ![main2.png](images/main2.png) ![main3.png](images/main3.png) [version 2016.05.04] Una de las ventajas de utilizar programas de computadoras es que podemos realizar tareas repetitivas fácilmente. Los ciclos como `for`, `while`, y `do-while` son estructuras de control que nos permiten repetir un conjunto de instrucciones. A estas estructuras también se les llama *estructuras de repetición*. En la experiencia de laboratorio de hoy utilizarás ciclos `for` para completar una aplicación de cifrado. ##Objetivos: 1. Aplicar estructuras de repetición para cifrar un mensaje. 2. Practicar operaciones aritméticas con caracteres. ##Pre-Lab: Antes de llegar al laboratorio debes: 1. Haber repasado los conceptos básicos relacionados a estructuras de repetición. 2. Haber repasado conceptos básicos de la clase `string` de C++,las funciones `length`, `toupper` y `push_back`, `isalpha` y las operaciones aritméticas con caracteres. 3. Haber visto el video sobre el "Ceasar Cypher" del Khan Academy, colocado en . 4. Haber visto el video sobre el "Vigenere Cypher", colocado en . 5. Haber estudiado los conceptos e instrucciones para la sesión de laboratorio. --- --- ##Criptografía La *criptografía* es un área que estudia la teoría y los métodos utilizados para proteger información de modo que personas que no estén autorizadas no puedan tener acceso a ella. Un *sistema criptográfico* es un sistema en el que la información (*mensaje* entendible por humanos) es tranformada a un texto cifrado inentendible para las personas no autorizadas a verlo. Las personas autorizadas a ver el mensaje usan un *descifrador* para revertir el texto cifrado al mensaje original. ###El Cifrado César (Ceasar Cypher) El Cifrado César es una técnica muy simple de cifrado por sustitución. Se dice que el sistema se basa en el sistema utilizado por Julio César, líder militar y político de Roma en años antes de Cristo, para comunicarse con sus generales. La técnica cifra un mensaje de texto sustituyendo cada letra del mensaje por la letra que se encuentra a un número dado de posiciones más adelante en el alfabeto. Esto puede pensarse como un desplazamiento ("shift") del alfabeto. El diagrama de la Figura 1 representa un desplazamiento de 3 espacios. La letra ‘B’ es sustituida por la letra ‘E’. --- ![figure1.png](images/figure1.png) **Figura 1.** Cifrador César con desplazamiento de 3 espacios. --- **Ejemplo 1:** Con un desplazamiento de 3 espacios, la palabra "ARROZ" quedaría cifrada como "DUURC". Nota que, con este desplazamiento de 3 espacios, la letra ‘Z’ es sustituida por la letra ‘C’. Cuando el desplazamiento se pasa de la letra ‘Z’ comenzamos nuevamente en la letra ‘A’. Esto se llama un desplazamiento cíclico. La Figura 2 muestra un desplazamiento cíclico de 8 espacios. --- ![figure2.png](images/figure2.png) **Figura 2.** Disco para cifrador César que muestra un desplazamiento de 8 espacios. --- ###Utilizando el operador módulo La operación de suma modular es esencial para implementar sistemas de cifrado en programación. En la aplicación de cifrado César de arriba podemos pensar que a cada letra del alfabeto (en inglés) le asignamos un número entre 0 y 25 (La `A` es 0, la`B` es 1, …, la `Z` es 25). El cifrador César convierte cada letra al número correspondiente en el intervalo [0, 25] y luego suma el desplazamiento. Para hacer el desplazamiento cíclico, cada vez que nuestro desplazamiento nos dé una letra que corresponda a un número mayor que 25, tomamos el residuo al dividir por 26 y usamos la letra que corresponda a ese residuo. Nota que tomar el residuo al dividir por 26 los resultados estarán entre 0 y 25, que son los valores asociados al alfabeto. El residuo al dividir dos números enteros se puede obtener utilizando el operador de *módulo*: `%`. Volviendo al Ejemplo 1, en la palabra "ARROZ", a la letra ‘Z’ le corresponde el número 25; al hacer un desplazamiento de 3 espacios, sumamos 3 a 25 y esto nos resulta en 28 que es un número mayor que 25. Si tomamos el residuo al dividir $25 + 3$ por 26, `(25 + 3) % 26`, obtenemos 2, que corresponde a la letra ‘C’. El proceso de arriba funciona si podemos asociar las letras de la ‘A’ a la ‘Z’ con los números del `0` al `25`. Esto se logra utilizando el valor numérico de los caracteres. Como en el código ASCII el valor de las letras ‘A’ a la ‘Z’ va desde 65 hasta 90, necesitamos hacer un ajuste en el cómputo de modo que a la `A` se le asigne `0`. Para convertir una letra mayúscula a un número en el intervalo [0, 25] solo tenemos que restar 65 (`’A’ - 65 = 0`, `’Z’ - 65 = 25`). Para cambiar un valor en el intervalo [0, 25] a la letra mayúscula que corresponde en el código ASCII solo tenemos que sumar 65 al número. Por ejemplo, el número 3 corresponde a la letra cuyo código ASCII es $3 + 65 = 68$, la letra ‘D’. La Figura 3 muestra el pseudocódigo para una algoritmo para el cifrador César. Cada letra ‘c’ en el mensaje se convierte a un número en el intervalo [0, 25] (restándole ‘A’), luego se hace el desplazamiento de d unidades al número (sumando d módulo 26). Finalmente se convierte el resultado al caracter correspondiente sumando el código ASCII de ‘A’. --- ```cpp Datos de entrada: un "string" de mensaje, la cantidad de desplazamiento d Datos de salida: el mensaje cifrado usando cifrado César 1. cypheredText = "" 2. para ("for") cada caracter c in en el mensaje: c = ascii(c) - ascii('A') # mueve c del intervalo [A,Z] al [0,25] c = ( c + d ) % 26 # desplaza (cíclicamente) c por d unidades c = ascii(c) + ascii('A') # mueve c del intervalo [0,25] al [A,Z] cypheredText.append(c) 3. devuelve ("return") cypheredText ``` **Figura 3.** Pseudo-código para cifrar utilizando un cifrador César. --- El cifrado César no es muy seguro ya que puede descifrarse fácilmente con un análisis de frecuencia. Por ejemplo, se sabe que en el idioma inglés la letra ‘e’ es la letra más frecuente en un texto. Si buscamos la letra que más se repite en un texto cifrado con un cifrador César, lo más probable es que esa fue la letra que se sustituyó por la ‘e’; con esto podemos deducir cuál fue desplazamiento utilizado y así descifrar el mensaje. ###El Cifrado Vigenere La debilidad principal del cifrador César es que cada letra en el mensaje se desplaza por el mismo número de posiciones. El cifrado Vigenere es un método de cifrado un poco más fuerte porque el desplazamiento en cada letra no es constante. El cifrado César recibe como datos de entrada el mensaje y un desplazamiento, mientras que el cifrado Vigenere recibe como dato de entrada el mensaje y una **clave** que determina el desplazamiento que se le hará a cada letra del mensaje. **Ejemplo 2.** Supongamos por el momento que tanto el mensaje como la clave tienen el mismo largo. Por ejemplo, suponga que el mensaje es "COSAS" y la palabra clave es "MENOR". La letra ‘C’ se parea con la letra ‘M’, la letra ‘O’ se parea con la letra ‘E’, la ‘S’ con la ‘N’, etcétera, como en la figura de abajo. Como la letra ‘A’ corresponde a un desplazamiento de 0 espacios, entonces la letra ‘M’ corresponde a un desplazamiento de 12 espacios, la ‘E’ a un desplazamiento de 4 espacios, etc. Utilizando la palabra clave "MENOR", el cifrador Vigenere hará un desplazamiento de 12 espacios a la letra ‘C’, un desplazamiento de 4 espacios a la letra ‘O’, etc., hasta obtener la palabra cifrada "OSFOJ" como se muestra en la Figura 4. --- | mensaje | C | O | S | A | S | |-----------------|---|---|---|---|---| | clave | M | E | N | O | R | | mensaje cifrado | O | S | F | O | J | **Figura 4.** Alineamiento del mensaje con la palabra clave y cifrado. --- Podemos visualizar un cifrador Vigenere utilizando una tabla como la de la Figura 5. Nota que lo que se hace es usar un cifrador César con un desplazamiento diferente para cada letra del mensaje. --- ![figure6.png](images/figure6.png) **Figura 5.** Tabla para cifrador Vigenere. --- Si la palabra clave es más corta que el mensaje, entonces repetimos la palabra clave tantas veces como haga falta, pareando letras del mensaje con letras de la palabra clave como se hace en la Figura 6. --- | mensaje | A | L | G | U | N | A | S | | C | O | S | A | S | |-----------------|---|---|---|---|---|---|---|---|---|---|---|---|---| | clave | M | E | N | O | R | M | E | N | O | R | M | E | N | | mensaje cifrado | M | P | T | I | E | M | W | | Q | F | E | E | F | **Figura 6.** Alineamiento del mensaje con la palabra clave y cifrado. --- ##Funciones que se utilizarán en esta experiencia de laboratorio: El programa que estarás modificando en la sesión de hoy utiliza los siguientes métodos de la clase `string`: * `length`: Devuelve el largo de un objeto de la clase `string`; esto es, `length` devuelve el número de caracteres que tiene el "string". Se utiliza escribiendo `.length()` después del nombre del objeto. * `push_back`: Este método recibe un caracter como argumento y lo añade al final del “string”. Se utiliza escribiendo `.push_back(elCaracter)` después del nombre del “string”. Por ejemplo, para añadir el caracter 'a' a un objeto de la clase `string` llamado `cadena`, escribimos `cadena.push_back('a')`. También utilizaremos las funciones: * `toupper`: Esta función recibe como argumento un caracter y devuelve el caracter en mayúscula. Por ejemplo, para cambiar el caracter 'a' a mayúscula se utiliza `toupper('a')`. * `isalpha`: Esta función recibe como argumento un caracter y devuelve un valor distinto de cero (`true`) si el caracter es una letra y cero (`false`) si el caracter no es una letra. Por ejemplo, `isalpha(3)` devuelve "false" pero `isalpha(‘F’)` devuelve `true`. --- --- !INCLUDE "../../eip-diagnostic/vigenere/es/diag-vigenere-01.html" !INCLUDE "../../eip-diagnostic/vigenere/es/diag-vigenere-02.html" !INCLUDE "../../eip-diagnostic/vigenere/es/diag-vigenere-03.html" --- --- ##Sesión de laboratorio: En esta experiencia de laboratorio completarás una aplicación para cifrar un mensaje de texto utilizando el cifrado Vigenere. Para simplificar el código, la clave y el mensaje deben consistir solo de letras y tu programa debe cambiar todas las letras del mensaje y la clave a mayúsculas. ###Ejercicio 1: Cifrador con clave y mensaje del mismo largo (solo letras) En este ejercicio completarás la aplicación para cifrar un mensaje de texto, que solo contiene letras, utilizando una palabra clave que también consiste solo de letras y que tiene el mismo largo del mensaje. ####Instrucciones 1. Descarga la carpeta Repetitions-VigenereCypher de Bitbucket usando un terminal, moviéndote al directorio Documents/eip, y escribiendo el comando git clone http://bitbucket.org/eip-uprrp/repetitions-vigenerecypher. 2. Carga a Qt Creator el proyecto VigenereCypher haciendo doble "click" en el archivo VigenereCypher.pro que se encuentra en la carpeta Documents/eip/Repetitions-VigenereCypher de tu computadora. 3. Estarás añadiendo código en el archivo `cypher.cpp`. En este archivo, la función `cypher` recibe un mensaje y una clave del mismo largo y consistentes solo de letras, y devuelve el mensaje cifrado por el cifrador Vigenere. Tu tarea es completar la función de cifrado. El código debe verificar si el mensaje y la clave consisten solo de letras y tienen el mismo largo; si esto no ocurre, el mensaje cifrado será (literalmente) `"MENSAJE O CLAVE INVALIDO"`. El programa debe implementar el cifrador Vigenere para ir cifrando cada letra del mensaje utilizando la clave. Solo debes utilizar las funciones mencionadas en la sección anterior. Para simplificar el código tu programa debe cambiar todas las letras del mensaje y la clave a mayúsculas. 4. Al terminar tu código, ve a la función `main` y descomenta la invocación a la función de prueba unitaria `test_cypher1`. Esa función realiza varias invocaciones a la función `cypher` para validar si sus resultados son correctos. Tu función `cypher` debe pasar todas las pruebas antes de continuar con la próxima parte de este laboratorio. ###Ejercicio 2: Cifrador con clave y mensaje de largos arbitrarios En este ejercicio modificarás el código de la función `cypher` que creaste para el Ejercicio 1 de modo que la aplicación ahora pueda cifrar cualquier mensaje utilizando una palabra clave que consista solo de letras pero que tenga cualquier largo. ####Instrucciones 1. Escribe el código de la función `cypher` para que reciba un mensaje y una clave y devuelva el mensaje cifrado por el cifrador Vigenere. En esta ocasión, el mensaje y la clave pueden tener cualquier largo y el mensaje puede tener cualquier caracter (la clave solo puede tener letras). El programa debe implementar el cifrador Vigenere para ir cifrando cada caracter del mensaje utilizando las letras de la clave. Para simplificar el código, tu programa debe cambiar todas las letras a mayúsculas. Si alguno de los caracteres del mensaje no es una letra, el cifrador no lo cambia, como se muestra en la Figura 7. Si alguno de los caracteres de la clave no es una letra, el mensaje cifrado será "CLAVE INVALIDA". Solo debes utilizar las funciones mencionadas en la sección anterior. --- | mensaje | A | L | & | U | N | A | $ | | C | O | S | A | S | |-----------------|---|---|---|---|---|---|---|---|---|---|---|---|---| | clave | M | E | N | O | R | M | E | N | O | R | M | E | N | | mensaje cifrado | M | P | & | I | E | M | $ | | Q | F | E | E | F | **Figura 7.** Ejemplo de mensaje y clave con largo distinto y símbolos en el mensaje. --- 2. Al terminar tu código, ve a la función `main`, comenta la invocación a la función de prueba unitaria `test_cypher1` y descomenta la invocación a la función de prueba unitaria `test_cypher2` para que verifiques tu programa. --- --- ##Entrega Utiliza "Entrega" en Moodle para entregar el archivo `cypher.cpp` que contiene la función `cypher` que creaste en el Ejercicio 2. Recuerda utilizar buenas prácticas de programación, incluir el nombre de los programadores y documentar tu programa. --- --- ##Referencias http://www.nctm.org/uploadedImages/Classroom_Resources/Lesson_Plans/ --- --- -----