Antecedentes
Un pad de una sola vez es una forma de cifrado que se ha demostrado que es imposible de descifrar si se usa correctamente.
El cifrado se realiza tomando un texto sin formato (compuesto solo por letras AZ) y generando una cadena aleatoria en la misma longitud (también solo letras). Esta cadena actúa como la clave. Cada carácter en el texto sin formato se empareja con el carácter correspondiente en la clave. El texto cifrado se calcula de la siguiente manera: para cada par, ambos caracteres se convierten en números (A = 0, B = 1, ... Z = 25). Los dos números se suman módulo 26. Este número se convierte de nuevo en un carácter.
El descifrado es exactamente lo contrario. Los caracteres en el texto cifrado y la clave se emparejan y se convierten en números. La clave se resta del módulo 26 de texto cifrado y el resultado se convierte de nuevo en un carácter AZ.
El reto
Su desafío es escribir el programa más corto posible que pueda cifrar y descifrar una libreta de una sola vez.
En la primera línea de entrada (a STDIN), habrá la palabra "ENCRYPT" o la palabra "DECRYPT".
Si la palabra está encriptada, la siguiente línea será el texto sin formato. Su programa debe generar dos líneas (a STDOUT), la primera es la clave y la segunda el texto cifrado.
Si la palabra se descifra, su programa obtendrá dos líneas más de entrada. La primera línea será la clave, y la segunda línea será el texto cifrado. Su programa debe generar una línea, que será el texto sin formato que se ha descifrado.
El texto sin formato, el texto cifrado y la clave siempre deben consistir en letras mayúsculas AZ. Siempre serán una sola línea y no contendrán espacios en blanco.
La clave siempre debe ser aleatoria. No se deben repetir partes grandes entre las ejecuciones, y no debe haber patrones que se puedan encontrar en el texto.
Dos ejemplos simples:
ENCRYPT
HAPPYBIRTHDAY
>ABKJAQLRJESMG
>HBZYYRTICLVME
DECRYPT
ABKJAQLRJESMG
HBZYYRTICLVME
>HAPPYBIRTHDAY
El >
representa lo que las líneas son de salida, por lo que no tiene que imprimir ese símbolo como salida.
fuente
/dev/random
,haveged
), cifrar xorreando los ords con los bytes y descifrar xormentándolos con la clave. gist.github.com/5078264 la clave o la aleatoriedad se pueden leer desde stdin, el mensaje o el texto cifrado pueden ser un argumento de nombre de archivo./dev/hwrng
, en lugar de usar pseudoaleatorio (lo que técnicamente hace que se rompa))Respuestas:
GolfScript, 53 caracteres
Esta es una tarea para la que GolfScript parece estar perfectamente adaptado.
Para mantener el código corto, estoy usando el mismo código tanto para el cifrado como para el descifrado: para descifrar, resta la clave del texto cifrado, mientras que para el cifrado, primero genero un texto cifrado aleatorio y luego le resta el texto plano. Aun así, el código adicional para implementar el modo de encriptación toma un poco más de la mitad de la longitud del programa.
Versión de golf con comentarios:
fuente
Rubí (
200185)ejecuciones de muestra + wc:
fuente
s[k=(p=f).map{rand 26}],r[k,p,:-]
debería escribirses[k=f.map{rand 26}],r[k,$_,:-]
$_
es solo la última línea leídagets
.f
También lo hace.scan(/./).map{|b|b.ord-65}
después de leer una línea.Haskell, 203 caracteres
Ejemplo:
fuente
Perl,
220171 caracteresEjecución de muestra:
Nota: al menos cuando lo ejecuto, "Presione cualquier tecla para continuar ..." se agrega al final de la última salida. Espero que esto esté bien, porque no es parte del programa. Si no, puedo hacerlo para que aparezca en la siguiente línea.
Este es mi primer programa real en Perl y mi primer golf, por lo que agradecería mucho los consejos. Además, encontré
/(.)/g
en Internet, pero no tengo idea de cómo funciona (¿es una expresión regular? Todavía no he aprendido esas). ¿Alguien me lo puede explicar?EDITAR: ¡Gracias a Ilmari Karonen por ayudarme con las expresiones regulares, usé mi nuevo conocimiento para salvar a 7 personajes!
Versión ampliada, ligeramente legible:
fuente
/(.)/g
es una expresión regular. Definitivamente querrás aprender esos si vas a jugar al golf Perl. perldoc.perl.org/perlre.html no es un mal punto de partida.Python -
304295Creo que esto cumple exactamente con las especificaciones
(incluidas las que se encuentranNo valida la entrada, por lo que creo que solo producirá basura si le da caracteres fuera de'>'
al comienzo de las solicitudes de entrada).[A-Z]
. También solo verifica la primera letra del comando de entrada. Todo lo que comienceD
resultará en un descifrado y cualquier otra cosa resultará en un cifrado.fuente
>
, solo lo estaba usando para demostrar qué líneas salían. No tienes que implementarlos.C ++ -
220241 caracteres, 4 líneasEditar 1- La biblioteca estándar de MSVS parece incluir muchos archivos innecesarios, lo que significa que iOS tenía todas las inclusiones que necesitaba, pero esto no funcionó con otros compiladores. Los ios modificados para los archivos reales que las funciones necesitadas aparecen en cstdlib y cstdio. Gracias a Ilmari Karonen por señalar esto.
fuente
g++ otp.cpp
diceotp.cpp: In function ‘int main()’: otp.cpp:3: error: ‘scanf’ was not declared in this scope otp.cpp:3: error: ‘rand’ was not declared in this scope otp.cpp:3: error: ‘puts’ was not declared in this scope otp.cpp:3: error: ‘puts’ was not declared in this scope
Python - 270
Salida de muestra:
Número de letras:
fuente
J: 94 bytes
Todo el espacio en blanco necesario contado.
Versión comentada:
fuente
C # (
445416)Olvidé sobre Aggregate. Cortar un poco.
Algo de golf:
}
Golfizado:
fuente
C (159 + 11 para banderas del compilador)
Golfizado:
Sin golf:
Compilar con
-Dg=gets(s)
.Ejemplo:
fuente
JavaScript 239
Uso:
fuente
Rubí -
184179177 caracteresEjecútelo así:
$ ruby pad-lock.rb
Esta es la versión sin golf si alguien está interesado (aunque no está muy actualizada con la de golf)
fuente