Skip to main content
This guide provides practical, ready-to-run examples for all three encryption algorithms. Copy and paste these examples to get started quickly.

Quick start examples

Basic encryption workflow

1

Start the server

pipenv shell
python app.py
2

Open browser

Navigate to http://localhost:5000
3

Encrypt a message

  1. Enter: HOLA MUNDO
  2. Select: Cifrar
  3. Choose: Sustitución (César)
  4. Click: Procesar ✨
  5. Result: OWSITCULW
4

Decrypt the result

  1. Copy the result: OWSITCULW
  2. Select: Descifrar
  3. Choose: Sustitución (César)
  4. Click: Procesar ✨
  5. Result: HOLAMUNDO

Caesar cipher (Sustitución) examples

The Caesar cipher shifts each letter by a fixed number of positions (default: 8).

Example 1: Simple message

import sustitucion

# Encrypt
mensaje = "HOLA"
pos = 8
cifrado = sustitucion.convertiraNumero(mensaje)
cifrado = sustitucion.cifrar(cifrado, pos)
result = sustitucion.convertiraLetra(cifrado)
print(f"Encrypted: {result}")  # Output: OWSI

# Decrypt
numeros = sustitucion.convertiraNumero(result)
descifrado = sustitucion.descifrar(numeros, pos)
original = sustitucion.convertiraLetra(descifrado)
print(f"Decrypted: {original}")  # Output: HOLA

Example 2: Longer message with spaces

InputOperationOutputNotes
HOLA MUNDOEncryptOWSITCULWSpaces removed
BUENOS DIASEncryptJCKLW×LASK×Includes special characters
OWSITCULWDecryptHOLAMUNDOSpaces not restored
The Caesar implementation removes spaces during encryption and doesn’t restore them during decryption. This is expected behavior.

Example 3: Spanish alphabet support

The implementation includes the Spanish letter Ñ:
# Message with Ñ
mensaje = "MAÑANA"
pos = 8

# The algorithm recognizes and shifts Ñ correctly
# A-Z plus Ñ creates a 27-character alphabet

Transposition cipher examples

The transposition cipher rearranges characters in a columnar matrix (default: 5 columns).

Example 1: Basic transposition

import transposicion

# Encrypt
mensaje = "HOLA MUNDO"
clave = 5
cifrado = transposicion.cifrar(mensaje, clave)
print(f"Encrypted: {cifrado}")  # Output: HUONLDAOM*

# Decrypt
descifrado = transposicion.descifrar(cifrado, clave)
print(f"Decrypted: {descifrado}")  # Output: HOLAMUNDO

Example 2: Understanding the matrix

With key=5, the message “HOLA MUNDO” is arranged in a 5-column matrix:
Step 1: Remove spaces → HOLAMUNDO (9 chars)
Step 2: Add padding → HOLAMUNDO* (10 chars, divisible by 5)

Step 3: Create matrix (5 columns):
┌───┬───┬───┬───┬───┐
│ H │ O │ L │ A │   │
├───┼───┼───┼───┼───┤
│ M │ U │ N │ D │ O │
└───┴───┴───┴───┴───┘

Step 4: Read by columns:
Column 1: H, M → HM
Column 2: O, U → OU
Column 3: L, N → LN
Column 4: A, D → AD
Column 5: (space), O → O

Result: Rearranged as HUONLDAOM*

Example 3: Different key sizes

mensaje = "HOLAMUNDO"
clave = 3

# Matrix (3 columns):
# H O L
# A M U
# N D O

# Result: Read columns → HAMOOLDNU
Larger keys create wider matrices and may require more padding. The key should be chosen based on message length for optimal security.

RSA encryption examples

RSA uses asymmetric encryption with public and private keys.

Example 1: Complete RSA workflow

import RSA

# Generate keys
bits = 32
e, d, n = RSA.gen_keys(bits)
print(f"Public key: e={e}, n={n}")
print(f"Private key: d={d}, n={n}")

# Encrypt
mensaje = "HOLA"
mensaje_cifrado = RSA.encrypt(mensaje, e, n)
print(f"Encrypted: {mensaje_cifrado}")
# Output: [123456789, 987654321, 456789123, 789123456]

# Decrypt
mensaje_descifrado = RSA.decrypt(mensaje_cifrado, d, n)
print(f"Decrypted: {mensaje_descifrado}")
# Output: HOLA

Example 2: Key generation details

import RSA

# Generate 32-bit keys
e, d, n = RSA.gen_keys(32)

print(f"Public exponent (e): {e}")
# Typically 65537 (a common choice)

print(f"Private exponent (d): {d}")
# Large number calculated from e and phi(n)

print(f"Modulus (n): {n}")
# Product of two prime numbers

# Key properties:
# - e and n are public (used for encryption)
# - d is private (used for decryption)
# - n is used for both encryption and decryption

Example 3: Web interface RSA session

1

First encryption

Input: SECRETO
Operation: Cifrar
Algorithm: RSA

Output:
[123, 456, 789, 101, 112, 131, 415]

Keys: e=65537, d=789456123, n=987654321
Keys are stored in the Flask session.
2

Decrypt the message

Input: [123, 456, 789, 101, 112, 131, 415]
Operation: Descifrar
Algorithm: RSA

Output: SECRETO
Uses keys from the session automatically.
3

Encrypt another message

Input: NUEVO
Operation: Cifrar
Algorithm: RSA

Output: [222, 333, 444, 555, 666]

Keys: e=17, d=234567890, n=123456789
New keys are generated, overwriting the previous ones.
Once you encrypt a new message, the previous RSA keys are lost. Save the keys if you need to decrypt old messages later.

Practical use case scenarios

Scenario 1: Comparing algorithm strengths

Test the same message with all three algorithms to understand their characteristics:
message = "ATAQUE AL AMANECER"

# Caesar: Easy to break with frequency analysis
# Output: IKICM×KISTI×J×F×L
# Weakness: Only 27 possible keys

# Transposition: Harder to break, preserves letter frequency
# Output: AAUR*QM*EA*LE*CT*AA*EN*DE*
# Weakness: Pattern analysis can reveal structure

# RSA: Strongest, but overkill for short messages
# Output: [large list of numbers]
# Strength: Computationally secure with proper key size

Scenario 2: Message length testing

mensaje = "HOLA"

# Caesar: OWSI
# Fast, simple

# Transposition: HLOA (with key=2)
# Minimal rearrangement

# RSA: [4 numbers]
# Works well, each char becomes one number

Scenario 3: Security demonstration

Demonstrate why these algorithms are educational only:
# Try all 27 possible shifts
for shift in range(27):
    decrypted = try_decrypt(ciphertext, shift)
    if looks_like_spanish(decrypted):
        print(f"Found! Shift = {shift}")
        print(f"Message: {decrypted}")
        break

Combining algorithms

For stronger encryption, you can apply multiple algorithms:
import sustitucion
import transposicion
import RSA

mensaje = "MENSAJE SECRETO"

# Step 1: Caesar cipher
pos = 8
cifrado1 = sustitucion.convertiraNumero(mensaje)
cifrado1 = sustitucion.cifrar(cifrado1, pos)
cifrado1 = sustitucion.convertiraLetra(cifrado1)
print(f"After Caesar: {cifrado1}")

# Step 2: Transposition
clave = 5
cifrado2 = transposicion.cifrar(cifrado1, clave)
print(f"After Transposition: {cifrado2}")

# Step 3: RSA
bits = 32
e, d, n = RSA.gen_keys(bits)
cifrado_final = RSA.encrypt(cifrado2, e, n)
print(f"Final encrypted: {cifrado_final}")

# To decrypt, reverse the order:
# RSA → Transposition → Caesar
Combining multiple ciphers can increase security, but proper implementation requires careful key management and understanding of each algorithm’s weaknesses.

Testing and validation

Verify that encryption and decryption work correctly:
def test_algorithm(encrypt_fn, decrypt_fn, mensaje):
    """Test that decrypt(encrypt(msg)) == msg"""
    cifrado = encrypt_fn(mensaje)
    descifrado = decrypt_fn(cifrado)
    
    # Remove spaces for comparison
    mensaje_clean = mensaje.replace(" ", "")
    descifrado_clean = descifrado.replace(" ", "").replace("*", "")
    
    if mensaje_clean == descifrado_clean:
        print(f"✓ Test passed for: {mensaje}")
        return True
    else:
        print(f"✗ Test failed for: {mensaje}")
        print(f"  Expected: {mensaje_clean}")
        print(f"  Got: {descifrado_clean}")
        return False

# Run tests
test_cases = [
    "HOLA",
    "HOLA MUNDO",
    "MENSAJE CON ESPACIOS",
    "A",
    "MAÑANA"
]

for test in test_cases:
    test_algorithm(caesar_encrypt, caesar_decrypt, test)

Performance considerations

AlgorithmSpeedMessage LengthBest Use Case
CaesarVery fastAnyQuick demos, learning
TranspositionFast< 1000 charsMedium messages
RSASlower< 100 charsSmall sensitive data
For the web interface, all three algorithms are fast enough for interactive use with typical message lengths (< 1000 characters).

Build docs developers (and LLMs) love