Programa de Cifrado César en Z80
Implementación detallada en ensamblador Z80 para cifrar cadenas terminadas en 0
Aspectos Clave
- Procesamiento de Cadenas: El programa recorre la cadena carácter a carácter hasta encontrar el terminador 0.
- Cifrado de Letras: Se aplica el desplazamiento definido para cifrar adecuadamente tanto letras mayúsculas como minúsculas.
- Manejo de Desbordamiento: Se emplea lógica para asegurar que el cifrado se mantenga dentro de los rangos ASCII válidos para letras.
Descripción General del Algoritmo
El cifrado César es un algoritmo de sustitución que consiste en reemplazar cada letra de un mensaje (texto plano) por otra, que se encuentra a un número fijo de posiciones en el alfabeto. Por ejemplo, con un desplazamiento de 3, la letra "A" se convierte en "D" y "Z" vuelve a "C" si se supera el final del alfabeto.
En nuestro programa en ensamblador Z80, la cadena de texto se almacena en memoria terminada por un byte 0. El programa recorre cada carácter, verifica si es una letra mayúscula o minúscula para aplicarle el cifrado, y utiliza lógica que evita el desbordamiento del rango de caracteres (respectivamente entre 'A'-'Z' y 'a'-'z'). Los caracteres que no correspondan a una letra se dejan sin modificar.
Detalles del Código
Sección de Definiciones
En este segmento se definen la cadena de texto que se desea cifrar y el valor del desplazamiento que se aplicará a cada carácter. La cadena finaliza con un 0 y el desplazamiento es un byte almacenado en memoria.
Ejemplo de Datos
; Definición de la cadena a cifrar y el desplazamiento
cadena:
db 'Hola, Mundo!',0 ; Cadena terminada en 0
desplazamiento:
db 3 ; Desplazamiento para el cifrado
Proceso de Recorrido y Cifrado
El algoritmo inicia convirtiendo la dirección de la cadena en el registro HL. Se recorre la cadena mediante un bucle que se repite hasta encontrar el byte 0, indicativo del final. En cada iteración, se carga el carácter actual en el registro A para su análisis.
Se determina si el carácter es una letra mayúscula comprobando que se encuentre entre 'A' y 'Z' o en minúscula entre 'a' y 'z'. Sólo en esos casos se aplica el cifrado. Salvo la aplicación del desplazamiento, se debe gestionar el caso en que la suma exceda el rango definido. Por ejemplo, si el desplazamiento hace que “Z” se convierta en un valor fuera de 'A'-'Z', se realiza una corrección para que vuelva al inicio del rango.
Manejo de Letras Mayúsculas
Para las letras mayúsculas, se verifica si, al sumarle el desplazamiento, el valor resultante excede 'Z' (ASCII 90). En ese caso, se resta 26 (número total de letras del alfabeto en inglés) para reiniciar dentro del rango.
Se realizan comparaciones utilizando las instrucciones CP y saltos condicionales para controlar el flujo. La estructura del programa garantiza que, si se sobrepasa el rango, el identificador se reajuste apropiadamente antes de almacenarse.
Manejo de Letras Minúsculas
El mismo proceso se aplica para las letras minúsculas. Al detectar un carácter comprendido entre 'a' (ASCII 97) y 'z' (ASCII 122), se le suma el desplazamiento y, si se excede 'z', se resta 26 para obtener el nuevo valor correcto.
Código Completo del Programa
A continuación se presenta el programa completo en ensamblador Z80 que realiza el cifrado César de una cadena de texto terminada en 0:
; Programa: Cifrado César en Z80
; Descripción: Cifra una cadena de texto almacenada en memoria, terminada en 0,
; aplicando un desplazamiento definido. El programa cifra letras mayúsculas y minúsculas,
; dejando inalterados otros caracteres.
ORG 0x0000 ; Punto de inicio del programa
;---------------------------------------------
; Datos de la Aplicación
;---------------------------------------------
cadena: db 'Hola, Mundo!',0 ; Cadena a cifrar seguida de terminador 0
desplazamiento: db 3 ; Valor de desplazamiento para el cifrado
;---------------------------------------------
; Inicio del Programa
;---------------------------------------------
inicio:
ld hl, cadena ; Cargar la dirección de la cadena en HL
;---------------------------------------------
; Bucle principal de cifrado: recorre cada carácter
;---------------------------------------------
cifrar:
ld a, (hl) ; Cargar el carácter actual en A
or a ; Comprobar si A es 0 (fin de cadena)
jr z, fin ; Si es 0, saltar a fin
; Comprueba si el carácter es una letra mayúscula: 'A' (65) a 'Z' (90)
cp 'A'
jr c, no_minuscula ; Si es menor que 'A', no es letra mayúscula
cp 'Z'
jr nc, revisar_minuscula ; Si es mayor que 'Z', puede ser minúscula o no letra
; Procedimiento para letras mayúsculas:
ld b, (desplazamiento) ; Cargar el desplazamiento en B
add a, b ; Cifrado: sumar el desplazamiento
cp 'Z'
jr jnc, corregir_mayus ; Si el valor superó 'Z', corregir el desbordamiento
jr guardar ; Sino, saltar a guardar el carácter modificado
revisar_minuscula:
; Comprueba si el carácter es una letra minúscula: 'a' (97) a 'z' (122)
cp 'a'
jr c, no_caracter ; Si es menor que 'a', no es letra
cp 'z'
jr nc, cifrado_no_aplicar ; Si es mayor que 'z', no se cifra
; Proceso para letras minúsculas:
ld b, (desplazamiento) ; Cargar desplazamiento en B
add a, b ; Sumar el valor del desplazamiento
cp 'z'
jr jnc, corregir_minus ; Si excede 'z', se corrige el valor
jr guardar ; Si está dentro del rango, se guarda directamente
;---------------------------------------------
; Corrección para letras mayúsculas que sobrepasan 'Z'
;---------------------------------------------
corregir_mayus:
; Se resta 26, reiniciando desde 'A'
sub 26
jr guardar
;---------------------------------------------
; Corrección para letras minúsculas que sobrepasan 'z'
;---------------------------------------------
corregir_minus:
sub 26
jr guardar
;---------------------------------------------
; Ruta para caracteres que no deben modificarse (no letras)
;---------------------------------------------
no_minuscula:
no_caracter:
; No se cifra el carácter, se sigue al siguiente
nop
jr guardar
;---------------------------------------------
; Guardar el carácter cifrado y avanzar en la cadena
;---------------------------------------------
guardar:
ld (hl), a ; Almacenar el carácter cifrado en la posición actual
inc hl ; Avanzar al siguiente carácter de la cadena
jr cifrar ; Repetir el proceso para el siguiente carácter
;---------------------------------------------
; Fin del programa
;---------------------------------------------
fin:
ret ; Salir del programa (en entornos embebidos, suele provocar reinicio o parada)
;---------------------------------------------
; Fin del código
;---------------------------------------------
Explicación Detallada por Secciones
Inicialización y Preparación
Al comienzo se define el origen de la memoria con la directiva ORG, que establece la dirección inicial de ejecución del programa.
Se definen además dos bloques de datos: el primero contiene la cadena que deseamos cifrar, y el segundo, el valor del desplazamiento.
La instrucción ld hl, cadena carga en el par de registros HL la dirección base donde se almacena la cadena de texto. Esto es fundamental para poder
acceder secuencialmente a cada carácter mediante el registro HL.
Bucle de Cifrado
El bucle denominado cifrar es el núcleo del programa donde se ejecuta el mecanismo de cifrado. En cada iteración se realiza lo siguiente:
- Lectura del Carácter: Se usa
ld a, (hl)para tomar el carácter actual y almacenarlo en el registro A. - Verificación del Terminador: La instrucción
or ase utiliza para comprobar si el carácter es 0. Si es así, se salta a la etiquetafinmediantejr z, fin. - Determinación del Tipo de Carácter: Dependiendo de si el carácter es una letra mayúscula o minúscula, se realiza una comparación con los límites ('A' y 'Z', o 'a' y 'z').
- Cifrado y Corrección: Se suma el desplazamiento (cargado en B) y se verifica si el nuevo valor sobrepasa el límite superior. Si lo supera, se resta 26 para que el rango se mantenga.
- Almacenamiento del Resultado: Tras aplicar el desplazamiento y cualquier corrección necesaria, el carácter procesado se vuelve a escribir en la cadena usando
ld (hl), a. - Avance en la Cadena: La instrucción
inc hlmueve la dirección de memoria al siguiente carácter, iniciando otra iteración del bucle.
Manejo de Caracteres No Letra
En caso de que el carácter actual no corresponda a una letra dentro de los rangos de mayúsculas o minúsculas, el programa hace un salto a la etiqueta
no_caracter donde se ignora el cifrado y se continúa con el siguiente carácter. Este control permite que símbolos, espacios y otros caracteres especiales se conserven intactos.
Finalización
Una vez se encuentra el terminador 0, se ejecuta la etiqueta fin y con la instrucción ret se finaliza la ejecución del programa.
Es importante destacar que en entornos embebidos o en sistemas sin un sistema operativo, esta instrucción puede provocar un reinicio o detener la ejecución.
Tabla Resumen del Flujo del Programa
| Etapa | Instrucción/Acción | Descripción |
|---|---|---|
| Inicialización | ORG, db, ld hl, cadena | Define el inicio del programa y carga la cadena a cifrar. |
| Lectura y Verificación | ld a, (hl) & or a | Se lee el carácter actual y se verifica si es el terminador (0). |
| Detección de Tipo de Carácter | cp 'A'-'Z' o cp 'a'-'z' | Determina si el carácter es elegible para ser cifrado. |
| Cifrado | add a, b | Suma el desplazamiento y corrige si hay desbordamiento. |
| Almacenamiento | ld (hl), a | Guarda el carácter cifrado en la posición correspondiente de la cadena. |
| Progreso | inc hl | Avanza al siguiente carácter de la cadena. |
| Terminación | jr z, fin & ret | Finaliza el bucle y termina la ejecución al encontrar el terminador 0. |
Aspectos Adicionales y Consideraciones
Es importante tener en cuenta lo siguiente al implementar y adaptar este programa:
- Adaptabilidad del Desplazamiento: Actualmente, el desplazamiento se encuentra almacenado en un byte específico de memoria. Puedes modificar este valor para probar diferentes claves de cifrado en función de tus necesidades. Asimismo, se podría potenciar este código para que acepte un valor variable o se solicite por entrada del usuario si el entorno lo permite.
- Robustez del Código: Aunque el ejemplo se ha diseñado para manejar adecuadamente letras mayúsculas y minúsculas, otros caracteres (números, signos de puntuación, etc.) permanecen inalterados. Si se desea ampliar la funcionalidad para incluir otros rangos o diferentes transformaciones, será necesario agregar lógica adicional.
- Optimización en Sistemas Embebidos: El código presentado es adecuado para demostraciones y entornos de aprendizaje. En aplicaciones en sistemas embebidos con recursos limitados, se deben tener en cuenta aspectos como la optimización de ciclos de CPU y el uso eficiente de la memoria.
- Verificación y Pruebas: Siempre es recomendable probar minuciosamente el programa con distintos valores de desplazamiento y cadenas con diferentes características para garantizar su correcto funcionamiento en todos los casos esperados.
- Compatibilidad: Aunque el programa se ha diseñado específicamente para procesadores Z80, los conceptos utilizados en el cifrado César son aplicables en otras arquitecturas. La adaptación a otros ensambladores o entornos de desarrollo implicará cambiar las directivas y, en ocasiones, la sintaxis, pero el algoritmo subyacente se mantiene igual.
Referencias
- Cifrado César en GitHub - GitHub
- Cifrado César en DEV006-cipher - DEV
- Cifrado César en dCode - dCode
- Caesar Cipher en Medium - Medium
- Cifrado César en GeeksforGeeks - GeeksforGeeks
Recomendaciones para Explorar Más
Last updated March 22, 2025