Edito para: Incluir la elegante solución de @cogier y para mostrar una comparativa de tiempos de cada uno de los métodos. El C está ausente por lo dicho al final del hilo —vamos, que no funciona—:
Código:
FacilCript.Main.36: A:24,84229375
FacilCript.Main.43: B:16,3204024537037
FacilCript.Main.57: D:29,4344163310185
FacilCript.Main.64: X:31,245717650463
Pues a raíz de otro comentario me puse a brujulear por la
página Rosetta Code, que me encanta, pero hacía un tiempo que no me pasaba por ahí, cuando vi que el algoritmo de Rot13 no estaba implementado para Gambas3.
El algoritmo Rot13, para los pocos que no lo sepan, es una manera de casi encriptar, de encriptar por diversión con un sistema bastante débil, mensajes en foros y antiguas listas de correos por el cifrado de César con un desplazamiento de 13 sobre 26 letras —es decir, la letra 1, la "A", se sustituye por la 14, "N", la "B" por la "O"... la "M" por la "A"—. Sí, justo un desplazamiento que es la mitad del abecedario anglosajón, por eso es reversible, es decir, al aplicar dos veces el algoritmo se obtiene el texto original.
Pues me puse a implementarlo de las dos maneras habituales: por sustitución directa o por rotación, y eso es lo que os traigo: Rot13_a y Rot13_b.
—Oiga, pero bueno, si hay una Rot13_c que no funciona. ¿Qué timo es éste?
Sí, ustedes disculpen. He estado intentando hacer la sustitución directa tal cual se hace en otro lenguajes, por ejemplo con el «tr» de Linux —vaaaale, podría haber empleado «shell» o «exec», pero me parecía que lo fundamental es emplear el propio Gambas3—, pero las funciones Gambas3 no tienen el mismo modo de funcionamiento. De todas maneras, si a alguien se le ocurre cómo, que chille.
—Venga, aceptamos pulpo, etc. Pero, ¿qué c.ñ. es eso de CriptoXOR?
Mire
usté, ya puestos me lie y, recordando esos juegos que tenían encriptados archivos con las características de las armas, coches o puntuaciones de forma poco, er, fuerte, y con un sistema sencillo y reversible, pues codifiqué algo parecido a lo que yo empleaba para conseguir el mejor tanque de un juego de los 90: A=((A XOR B) XOR B).
En fin, me voy a almorzar —ahora se llama
brunch—. Os dejo con el código.
—Pero bueno, ¿todo este rollo para una chorrada? Pero no se vaya, oiga..., oiga...
Código:
' Gambas module file
Public Sub Main()
Dim Textos As New String[]
Dim Texto As String
Dim Clave As Byte = 13
Dim i As Integer
Dim Max As Integer = 1000000
Dim Tic, Tac As Date
Textos.Add("En un lugar de La Mancha con tildes: áéíóúÁÉÍÓÚüÜñÑ¡!1234567890")
Textos.Add("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz")
Textos.Add("Cthulhu R'lyeh Ph'nglui mglw'nafh wgah'nagl fhtagn")
Texto = Textos[0]
Debug " "; Texto
Debug "A: "; Rot13_a(Texto)
Debug " "; Rot13_a(Rot13_a(Texto))
Debug "B: "; Rot13_b(Texto)
Debug " "; Rot13_b(Rot13_b(Texto))
Debug "C: "; Rot13_c(Texto)
Debug " "; Rot13_c(Rot13_c(Texto))
Debug "D: "; Rot13_d(Texto)
Debug " "; Rot13_d(Rot13_d(Texto))
Debug "X: "; CriptoXOR(Texto, Clave)
Debug " "; CriptoXOR(CriptoXOR(Texto, Clave), Clave)
Tic = Timer
For i = 1 To Max
Rot13_a(Texto)
Next
Tac = Timer
Debug "A:"; Tac - Tic
Tic = Timer
For i = 1 To Max
Rot13_b(Texto)
Next
Tac = Timer
Debug "B:"; Tac - Tic
' Tic = Timer
' For i = 1 To Max
' Rot13_c(Texto)
' Next
' Tac = Timer
' Debug "C:"; Tac - Tic
Tic = Timer
For i = 1 To Max
Rot13_d(Texto)
Next
Tac = Timer
Debug "D:"; Tac - Tic
Tic = Timer
For i = 1 To Max
CriptoXOR(Texto, Clave)
Next
Tac = Timer
Debug "X:"; Tac - Tic
End
Private Function CriptoXOR(Texto As String, Clave As Byte) As String
Dim Parte As New String[]
Dim Total As String
Dim i As Integer
For i = 0 To Len(Texto) - 1
Parte.Add(String.Chr(String.Code(Texto, i + 1) Xor Clave))
Next
Total = Parte.Join("")
Return Total
End
Public Function Rot13_a(Texto As String) As String
Dim i, d As Integer
Dim Total As String
For i = 0 To Len(Texto) - 1
d = Asc(Texto[i, 1])
If d >= 65 And d <= 90 Then
d += 13
If d > 90 Then d -= 26
End If
If d >= 97 And d <= 122 Then
d += 13
If d > 122 Then d -= 26
End If
Total = Total & Chr(d)
Next
Return Total
End Function
Public Function Rot13_b(Texto As String) As String
Dim a As String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
Dim b As String = "NOPQRSTUVWXYZABCDEFGHIJKLMnopqrstuvwxyzabcdefghijklm"
Dim Total As String = Texto
Dim c As String
Dim i As Integer
For i = 0 To Len(Total) - 1
c = Total[i, 1]
If InStr(a, c) Then Mid(Total, i + 1, 1) = b[InStr(a, c) - 1, 1]
Next
Return Total
End
Public Function Rot13_c(Texto As String) As String
Dim Total As String
Exec ["tr", "a-zA-Z", "n-za-mN-ZA-M", "<<<" & Shell$(Texto)] Wait To Total
Return Total
End
Private Function Rot13_d(Texto As String) As String 'Cogier
Dim sChars As String = "abcdefghijklmnopqrstuvwxyzabcdefghijklm"
Dim iLoop As Integer
Dim bUCase As Boolean
Dim sWork As String
Dim Label As String
Label = ""
For iLoop = 1 To Len(Texto)
sWork = Texto[iLoop - 1]
bUCase = IsUpper(sWork)
If InStr(sChars, LCase(sWork)) > 0 Then sWork = sChars[InStr(sChars, LCase(sWork)) + 12]
If bUCase Then sWork = UCase(sWork)
Label &= sWork
Next
Return Label
End
Salidas:
Código:
FacilCript.Main.19: En un lugar de La Mancha con tildes: áéíóúÁÉÍÓÚüÜñÑ¡!1234567890
FacilCript.Main.20: A: Ra ha yhtne qr Yn Znapun pba gvyqrf: áéíóúÁÉÍÓÚüÜñÑ¡!1234567890
FacilCript.Main.21: En un lugar de La Mancha con tildes: áéíóúÁÉÍÓÚüÜñÑ¡!1234567890
FacilCript.Main.22: B: Ra ha yhtne qr Yn Znapun pba gvyqrf: áéíóúÁÉÍÓÚüÜñÑ¡!1234567890
FacilCript.Main.23: En un lugar de La Mancha con tildes: áéíóúÁÉÍÓÚüÜñÑ¡!1234567890
FacilCript.Main.24: C:
FacilCript.Main.25:
FacilCript.Main.26: D: Ra ha yhtne qr Yn Znapun pba gvyqrf: áéíóúÁÉÍÓÚüÜñÑ¡!1234567890
FacilCript.Main.27: En un lugar de La Mancha con tildes: áéíóúÁÉÍÓÚüÜñÑ¡!1234567890
FacilCript.Main.28: X: Hc-xc-axjl-ih-Al-@lcnel-nbc-ydaih~7-ìäàþ÷ÌÄÀÞ×ñÑüܬ,<?>98;:54=
FacilCript.Main.29: En un lugar de La Mancha con tildes: áéíóúÁÉÍÓÚüÜñÑ¡!1234567890
FacilCript.Main.36: A:24,84229375
FacilCript.Main.43: B:16,3204024537037
FacilCript.Main.57: D:29,4344163310185
FacilCript.Main.64: X:31,245717650463
PS.—Si alguien encuentra cómo simplificar los algoritmos, que chille, me hace el favor. Y ya puestos, que lo suba a Rosetta, que a mí me da pereza