IPC

Universidad de San Carlos

Segundo semestre 2021


Semana 0 Scratch

Semana 1 C

Semana 2 Arrays

Semana 3 Algoritmos

Semana 4 Memoria

Semana 6 Python

Proyecto Final


Programa de estudios

Horas de oficina

Conjuntos de problemas

Preguntas Frecuentes


Text editor

GitHub

Manual

Scrath

Guías de estilo

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/63fd8be9-afbf-4e82-8e87-5fc4a2b5deca/Untitled.png

Cesar


Implemente un programa que encripte mensajes usando el cifrado de Caesar, según lo siguiente.

$ ./caesar 13
plaintext: HELLO
ciphertext: URYYB

Fondo

Supuestamente, César solía "encriptar" (es decir, ocultar de manera reversible) mensajes confidenciales al desplazar cada letra en un cierto número de lugares. Por ejemplo, podría escribir A como B, B como C, C como D,… y, en orden alfabético, Z como A. Entonces, para decir HELLO a alguien, César podría escribir IFMMP. Al recibir tales mensajes de César, los destinatarios tendrían que "descifrarlos" cambiando las letras en la dirección opuesta en el mismo número de lugares.

El secreto de este "criptosistema" dependía de que sólo César y los destinatarios conocieran un secreto, el número de lugares por los que César había cambiado sus letras (por ejemplo, 1). No es particularmente seguro para los estándares modernos, pero, bueno, si quizás eres el primero en el mundo en hacerlo, ¡bastante seguro!

El texto no cifrado generalmente se denomina texto sin formato . El texto cifrado generalmente se denomina texto cifrado . Y el secreto utilizado se llama clave .

Para ser claros, entonces, así es como se *HELLO* obtiene el cifrado con una clave de 1 IFMMP:

Untitled

Untitled

Más formalmente, el algoritmo de Caesar (es decir, el cifrado) cifra los mensajes "rotando" cada letra en k posiciones. Más formalmente, si p es un texto plano (es decir, un mensaje no cifrado), pi es el i-ésimo carácter en p, y k es una clave secreta (es decir, un número entero no negativo), entonces cada letra, ci , en el texto cifrado, c , se calcula como

$c_y = (p_y + k) \% 26$

donde *% 26* aquí significa "resto al dividir por 26". Esta fórmula quizás hace que el cifrado parezca más complicado de lo que es, pero en realidad es solo una forma concisa de expresar el algoritmo con precisión. De hecho, en aras de la discusión, piense en A (o a) como 0, B (o b) como 1, ..., H (o h) como 7, I (o i) como 8, ... y Z (o z) como 25. Suponga que César solo quiere saludar a alguien que usa, en forma confidencial, esta vez, una clave, k , de 3. Y entonces su texto llano, p , es Hola, en cuyo caso el primer carácter de su texto llano, p_0 , es H (también conocido como 7), y el segundo carácter de su texto sin formato, p_1 , es i (también conocido como 8). El primer carácter de su texto cifrado, c_0, es así K, y el segundo carácter de su texto cifrado, c_1 , es así L. ¿Puedes ver por qué?

Escribamos un programa llamado *caesar* que le permita cifrar mensajes usando el cifrado de Caesar. En el momento en que el usuario ejecuta el programa, debe decidir, proporcionando un argumento de línea de comandos, cuál debe ser la clave en el mensaje secreto que proporcionará en tiempo de ejecución. No debemos asumir necesariamente que la clave del usuario será un número; aunque puede suponer que, si es un número, será un entero positivo.

A continuación, se muestran algunos ejemplos de cómo podría funcionar el programa. Por ejemplo, si el usuario ingresa una clave de 1 y un texto sin formato de *HELLO*:

$ ./caesar 1
plaintext:  HELLO
ciphertext: IFMMP

Así es como el programa podría funcionar si el usuario proporciona una clave *13* y un texto sin formato de *hello, world*:

$ ./caesar 13
plaintext:  hello, world
ciphertext: uryyb, jbeyq

Observe que ni la coma ni el espacio fueron "desplazados" por el cifrado. ¡Solo rota los caracteres alfabéticos!

¿Qué tal uno más? Así es como el programa podría funcionar si el usuario proporciona una clave de 13 nuevo, con un texto plano más complejo:

$ ./caesar 13
plaintext:  be sure to drink your Ovaltine
ciphertext: or fher gb qevax lbhe Binygvar

Intentalo!

Para probar la implementación de este problema por parte del personal, ejecute

./caesar key

sustituyendo un entero válido en lugar de key, dentro de esta caja de arena.

Especificación

Diseñe e implemente un programa, caesar que encripta mensajes usando el cifrado de Caesar.

Como empezar Abordemos este problema paso a paso.

Pseudocódigo

Primero, escriba un pseudocódigo que implemente este programa, incluso si no está seguro (¡todavía!) De cómo escribirlo en código. No hay una forma correcta de escribir pseudocódigo, pero son suficientes oraciones cortas en inglés. Recuerde cómo escribimos el pseudocódigo para encontrar a Mike Smith. Las probabilidades son que su pseudocódigo usará (¡o implicará usar!) Una o más funciones, condiciones, expresiones booleanas, bucles y / o variables.

Contar argumentos con la línea de comandos

Cualquiera que sea su pseudocódigo, primero escribamos solo el código C que verifica si el programa se ejecutó con un solo argumento de línea de comando antes de agregar funcionalidad adicional.

Específicamente, modifique caesar.cde tal manera que: si el usuario proporciona exactamente un argumento de línea de comando, imprima Success; si el usuario no proporciona argumentos en la línea de comandos, o dos o más, imprime Usage: ./caesar key. Recuerde, dado que esta clave proviene de la línea de comandos en tiempo de ejecución, y no a través de get_string, no tenemos la oportunidad de volver a solicitar al usuario. El comportamiento del programa resultante debería ser como el siguiente.

$ ./caesar 20
Success

o

$ ./caesar
Usage: ./caesar key

o

$ ./caesar 1 2 3
Usage: ./caesar key

Accediendo a la llave

Ahora que su programa (¡con suerte!) Está aceptando la información prescrita, es hora de dar otro paso.

Recuerde que en nuestro programa, debemos defendernos de los usuarios que técnicamente proporcionan un único argumento de línea de comandos (la clave), pero proporcionan algo que en realidad no es un número entero, por ejemplo:

$ ./caesar xyz

Sin embargo, antes de comenzar a analizar la clave para determinar su validez, asegurémonos de poder leerla. Modifique aún más caesar.c de manera que no solo verifique que el usuario haya proporcionado solo un argumento de línea de comando, sino que, después de verificarlo, imprima ese único argumento de línea de comando. Entonces, por ejemplo, el comportamiento podría verse así:

$ ./caesar 20
Success
20

Validando la llave

Ahora que sabes leer la clave, analicémosla. Modifica caesar.c de tal manera que en lugar de imprimir el argumento de línea de comandos proporcionada, su programa en lugar comprobaciones para asegurarse de que cada personaje de ese argumento de línea de comandos es un dígito decimal (es decir, 0, 1, 2, etc.) y, si alguno de ellos no lo son , termina después de imprimir el mensaje Usage: ./caesar key. Pero si el argumento consta únicamente de caracteres de dígitos, debe convertir esa cadena (recuerde que argves una matriz de cadenas, incluso si esas cadenas parecen números) en un entero real e imprimir el entero , como via %icon printf. Entonces, por ejemplo, el comportamiento podría verse así:

$ ./caesar 20
Success
20

o

$ ./caesar 20x
Usage: ./caesar key

Mirando debajo del capó

Como seres humanos es fácil para nosotros entender intuitivamente la fórmula descrita anteriormente, en la medida en que podemos decir “H + 1 = I”. Pero, ¿puede una computadora entender esa misma lógica? Vamos a averiguar. Por ahora, ignoraremos temporalmente la clave que proporcionó el usuario y, en su lugar, le pediremos un mensaje secreto e intentaremos cambiar todos sus caracteres en solo 1.

Extienda la funcionalidad de caesar.c tal que, después de validar la clave, solicitemos al usuario una cadena y luego cambiemos todos sus caracteres en 1, imprimiendo el resultado. También en este punto probablemente podemos eliminar la línea de código que escribimos anteriormente que se imprime Success. En total, esto podría resultar en este comportamiento:

$ ./caesar 1
plaintext:  hello
ciphertext: ifmmp

Tu turno!

¡Ahora es el momento de unir todo! En lugar de cambiar los caracteres en 1, modifíquelos *caesar.c* para cambiarlos por el valor de clave real. ¡Y asegúrese de conservar el estuche! Las letras mayúsculas deben permanecer en mayúsculas, las minúsculas deben permanecer en minúsculas y los caracteres que no son alfabéticos deben permanecer sin cambios.

Cómo probar tu código


Ejecute lo siguiente para evaluar el estilo de su código usando style50.

style50 caesar.c

Cómo enviar

Calificación presencial a partir del 5 de octubre