¡Están en juego 10.000 puntos para el ganador!

Mi primera intervención va a ser para presentaros un algoritmo de cifrado que utilizo desde hace tiempo: TFTR. Las iniciales evocan a los tokamaks, ya sabéis: esas máquinas toroidales, donde se intenta confinar la fusión nuclear, transmutando el hidrógeno en helio; y ya se sabe que cifrar va de cambiar ciertas cosas por otras, a ser posible con algo circular implicado en ello.

Después de esto parece que este cifrado será algo muy complejo, pero no, al contrario: es sencillísimo, es un cifrado simétrico que usa una clave nemotécnica y creo que es bastante seguro: a ver qué opináis...

Normalmente utilizo la tabla ASCII, pero en este ejemplo utilizaré un alfabeto reducido, de 32 símbolos; así con 5 bits me funciona el operador XOR de VB.

  1. 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
  2. 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 _ . @ * ,

Por ejemplo, utlizamos la clave SANCHO para cifrar el primer párrafo del Quijote:

  1. EN_UN_LUGAR_DE_LA_MANCHA,_DE_CUYO_NOMBRE_NO_QUIERO_ACORDARME,_NO_HA_MUCHO_TIEMPO_QUE_VIVIA_UN_HIDALGO_DE_LOS_DE_LANZA_EN_ASTILLERO,_ADARGA_ANTIGUA,_ROCIN_FLACO_Y_GALGO_CORREDOR.

Lo primero que hacemos es sumar los valores de los caracteres de la clave:

  1. S A N C H O
  2. 19 + 0 + 13 + 2 + 7 + 15 = 56

Ahora sumamos los dígitos del resultado:

  1. 5 + 6 = 11

multiplicamos este resultado por el anterior:

  1. 56 * 11 = 616

Ahora obtenemos el módulo con la longitud del mensaje:

  1. 616 mod 177 = 85

Estas operaciones las realizamos para obtener la posición del caracter que vamos a cifrar; en este caso hemos obtenido la posición 85, que está ocupada por la letra V en el mensaje.

A continuación hacemos un XOR entre el valor del primer carácter de la clave (S) y V:

  1. 19 XOR 22 = 5

5 es el valor del carácter F que pasará a ocupar la posición 85 del texto cifrado.

Además, la primera posición de la clave se cambia por V: VANCHO

Proseguimos con esta lógica y recalculamos el valor de la clave:

  1. 22+0+13+27+15=59; 5+9=14; 59*14=826;826 mod 177=118

La posición 118 está ocupada por la E. Haciendo un XOR con la segunda posición de la clave tenemos:

  1. 0 XOR 4 = 4

En el caso de que la posición obtenida pertenezca a un carácter ya cifrado, buscaremos por la derecha la primera posición pendiente. Si nos "salimos" del mensaje, como siempre comenzaremos por el principio.

La posición 118 del texto cifrado será una E; además cambiaremos la segunda posición de la clave: VENCHO.

Una vez que lleguemos al final de la clave daremos la vuelta, utilizando la primera posición. De esta forma la clave varía continuamente durante el cifrado, utilizando los caracteres del texto en claro, tomados de una forma no consecutiva, por lo que (en mi inocencia) me parece un cifrado muy seguro; quizá entonces vosotros podáis sacarme de mi error. Además no es muy difícil de aplicar manualmente, con lápiz y papel.

El texto cifrado es:

  1. ,XJRLV*ZCUHVIEA@_ABLVEFA.TÑTAYÑTTTB.BZ@V_FOJ**L,YTAMSA*DUÑEBACCJXHL.*QV.OTTAADTNA@HLCFSNIN.QJAXDFQIJDPQQ_IHWSHMAJGÑBAJEOJ_SPLLTG,_PVAQI,@E.EGÑKAQU,PJZCI*JEE_VTTCY@EDETTYAEJ_XMRQ

Añado un módulo de visual basic, donde está implementado este algoritmo; como véis no es un proceloso programa de páginas y páginas, es bastante sencillo.

Bueno, ya me diréis...

Function cifrar(clave_i, entrada_i, cifrar_descifrar)

Dim mensaje() As String
Dim clave() As String

longitud = Len(entrada_i)
lclave = Len(clave_i)

ReDim mensaje(longitud)
ReDim clave(lclave)

For i = 1 To longitud
  mensaje(i - 1) = Mid$(entrada_i, i, 1)
Next i
For i = 1 To lclave
  clave(i - 1) = Mid$(clave_i, i, 1)
Next i


cifrado = String(longitud, "-")
ya_ocupada = String(longitud, "-")
posicion_clave = -1

For t = 1 To longitud

   posicion_clave = posicion_clave + 1
   posicion_clave = posicion_clave Mod lclave

   x = sumar_clave(clave(), longitud)
   Do
    ya_cifrado = Mid$(ya_ocupada, x + 1, 1)
     If ya_cifrado = "*" Then
       x = x + 1
       x = x Mod longitud
     End If
   Loop Until ya_cifrado <> "*"

  letra = mensaje(x)
  Mid$(ya_ocupada, x + 1, 1) = "*"
  y = inv_caracter(clave(posicion_clave)) Xor inv_caracter(letra)

  Mid$(cifrado, x + 1, 1) = caracter(y)
  
  If cifrar_descifrar = "C" Then
     clave(posicion_clave) = letra
   Else
     clave(posicion_clave) = caracter(y)
  End If
  
  Next t

cifrar = cifrado

End Function
Function sumar_clave(clave() As String, longitud)

total = 0
For i = 0 To UBound(clave) - 1
  a = clave(i)
  x = inv_caracter(a)
  total = total + x
Next i

cadena = Format$(total, "000000")
resuma = 0
For i = 1 To Len(cadena)
  resuma = resuma + CDbl(Mid$(cadena, i, 1))
Next i
total = total * resuma

total = total Mod longitud
sumar_clave = total

End Function
Function caracter(numero)
  caracteres = Array("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", "_", ".", "@", "*", ",")
  caracter = caracteres(numero)
End Function
Function inv_caracter(caracter)
  caracteres = Array("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", "_", ".", "@", "*", ",")
  For i = 0 To 31
   If caracteres(i) = caracter Then inv_caracter = i: Exit Function
  Next i
End Function