encryption code-golf xor

Código de Golf: XOR Encryption



code-golf (23)

F #, 168 caracteres

open System.IO [<EntryPoint>] let main a= let k=File.ReadAllBytes a.[1] let z i v=v^^^k.[i%k.Length] File.WriteAllBytes(a.[0], Array.mapi z (File.ReadAllBytes a.[0])) 0

Nota: Mayormente IO, la clave es Array.mapi. Además, algunos F # Guru probablemente se vayan de la solución: soy un programador C # de oficio, y nunca usé F # para nada más que aprender por diversión.

De : Encryption Co.
Para : x $ * sj4 (ese eres tú)

Su misión, si decide aceptarla, es crear un programa en el menor número de teclas que

  • Toma dos parámetros de nombre de archivo (ya sea línea de comando o stdin), el primero es un archivo que contiene la clave y el segundo algún mensaje. Ambos archivos serán texto sin formato.

  • Aplica la clave del mensaje usando el cifrado XOR , sobrescribiendo el archivo.

Ejemplo:

Fichero de entrada:

StackOverflow es genial

Llave:

Código Golf

Hex dump del archivo de salida cifrado:

0000000: 101b 0506 4b08 1909 1425 030b 1200 2e1c ....K....%...... 0000010: 4c25 2c00 080d 0a L%,....

Para simplificar, suponga que los archivos pueden caber en la memoria

Este mensaje se autocifrará en 5 ... 4 ... 3 ... 2 ... 1 ...

##### #### _/_ ________ ##=-[.].]| / / #( _/ | |------| # __| | |||||||| / _/ | |||||||| .--''--''-. | | ____ | / __ `|__|[o__o]| _(____nm_______ /____/____

El cifrado XOR es imposible de descifrar si el tamaño de la clave es mayor o igual al tamaño del mensaje y la clave se genera mediante un proceso aleatorio imparcial. Ver: almohadilla de una sola vez . Entonces no hay "Pobre Cifrado" aquí.


Haskell, 181 caracteres

I / O es una perra al jugar al golf en Haskell, y la E / S binaria doblemente. Esta solución probablemente puede mejorarse enormemente. ¡Sentirse libre!

import Data.Bits import Data.ByteString as B u=unpack g o[l,n]=o$pack$Prelude.zipWith xor(u n)(cycle$u l) f x=mapM B.readFile x>>=g(B.writeFile$x!!1) main=Prelude.getLine>>=f.words

Uso:

$ ghc --make encrypt.hs $ echo -n ''Code Golf'' > key $ echo -n '' is Cool'' > message $ echo ''key message'' | ./encrypt $ od -tx1 message


KSH93 - 152 caracteres

m=$(<$1) k=$(<$2) for ((e=0;e<${#m};e++)) do out="$out$(printf "%02X" $(("''${m:$e:1}"^"''${k:${e}%${#k}:1}")))" done echo "${out}0d0a" | xxd -p -r >$1


PowerShell, 125 115 caracteres

Hasta ahora, esta parece ser la respuesta más corta basada en .net:

$k=[char[]](gc $args[1]);$i=0;sc $args[0] ([byte[]]([char[]](gc $args[0])|%{$_ -bXor $k[$i++%$k.Length]})) -en byte

Versión bonita con abreviaturas de comando explicadas:

$k=[char[]](get-content $args[1]) $i=0 set-content ` $args[0] ` ([byte[]] ([char[]] (get-content $args[0]) ` | foreach {$_ -bXor $k[$i++ % $k.Length]})) ` -encoding byte

Uso: powershell codegolf.ps1 message.txt key.txt . Según lo solicitado, sobrescribe message.txt .


Ruby - 158 caracteres

def a(b);File.readlines(b).join("/n").chomp;end;t=a($*[0]);k=a($*[1]);File.open($*[0],"w"){|f|0.upto(t.length-1){|i|f.putc((t[i]^k[i.modulo(k.length)]).chr)}}

Una versión más bonita:

def a(b) File.readlines(b).join("/n").chomp end t = a($*[0]) k = a($*[1]) File.open($*[0],"w") {|f| 0.upto(t.length - 1) {|i| f.putc((t[i] ^ k[i.modulo(k.length)]).chr) } }

Esta solución aprovecha el siguiente aspecto del problema:

Su misión, si decide aceptarla, es crear un programa en el menor número de teclas que ...

Esta solución fue escrita en mi tableta utilizando el reconocimiento de escritura a mano como entrada. No se tocaron claves en la creación de este código. Por lo tanto, este programa se desarrolló en cero pulsaciones de teclas. Termina el juego, yo gano!


Arrepentirse, 13 7 caracteres (sin soporte de archivos), 14 caracteres (con soporte de archivos)

Repent es un lenguaje de juguete esotérico basado en stack, con inspiración de J, APL, Golfscript y Python. Aquí hay una solución corta. Lo explicaré, pero es muy tarde y me estoy metiendo de cabeza, así que lo explicaré y lanzaré un intérprete de Silverlight por la mañana.

↓↷¦*⊕;€

Explicación:

↓ Copies the message string back onto the stack ↷ Puts the extra message string to the bottom of stack ¦ Find length of message string * Multiply key array by last number - repeats key for at least as long as message ⊕; Apply XOR between each element corresponding of message array and repeated key array, pushing XOR encoded message to stack € Print encoded message string/(char array) as string.

Use como:

Repent "↓↷¦*⊕;€" "Code Golf" " is Cool" > output.txt

Salida (la mayoría de los caracteres no se muestran):

Ascii: K % .L%, Hex: 10 1B 05 06 4B 08 19 09 14 25 03 0B 12 00 2E 1C 4C 25 2C 00 08 0D 0A

Usando archivos es:

↓↶▲⇄▲↓3↔⇄¦*⊕;▼

Referencia del lenguaje (sin terminar)

Intérprete (sin terminar)


C - 163 161 caracteres

Se agregó color y se eliminó la búsqueda innecesaria.

golfed:

#include <stdio.h> int*p,l;char*k;main(int c,char**v){FILE*f=fopen(*++v,"rb+");k=p=*++v;while(fgets(&l,2,f)){fseek(f,-1,1);putc(l^*k++,f);fflush(f);if(!*k)k=p;}}

sin sentido:

#include <stdio.h> int*p,l; char*k; main(int c,char**v){ FILE*f=fopen(*++v,"rb+"); k=p=*++v; while(fgets(&l,2,f)){ fseek(f,-1,1); putc(l^*k++,f); fflush(f); if(!*k)k=p; } }


F#, 147 146 caracteres

Esto se basa en gran medida en la solución de driis . Todo lo que hice fue agregar la sangría necesaria para que compilara, cambiara el orden de los parámetros de la línea de comando y ajustó las cosas. Sin embargo, no me sorprendería que todavía se pueda acortar un poco. Nota: recibirá una advertencia sobre coincidencias de patrones incompletos. Por lo general, yo sería el primero en quejarme de esto, pero creo que el código golf merece una excepción a las mejores prácticas habituales. :)

open System.IO[<EntryPoint>]let m[|a;b|]=File.ReadAllBytes|>fun r->r a|>fun k->File.WriteAllBytes(b,Array.mapi(fun i->(^^^)k.[i%k.Length])(r b));0

F #, 147 caracteres, más legible

open System.IO let r=File.ReadAllBytes [<EntryPoint>] let m[|a;b|]= let k=r a File.WriteAllBytes(b,Array.mapi(fun i->(^^^)k.[i%k.Length])(r b));0


GolfScript, 28 caracteres

n.+/~:k;.,.)k.,@//)*<{/(@^}%

Para usar, pase el archivo del mensaje, seguido de una nueva línea, seguido del archivo de la clave a la entrada estándar del guión:

$ (cat message-file ; echo ; cat key-file) | ruby golfscript.rb poorencrypt.gs

$ (echo is Cool;echo;echo Code Golf) | / ruby golfscript.rb poorencrypt.gs > encoded-file $ (cat encoded-file;echo;echo Code Golf) | ruby golfscript.rb poorencrypt.gs is Cool


Java, 336 316 405 caracteres

EDITAR: Olvidé que tenía que leer de un archivo. *suspiro

public class A { public static void main(String[] a) throws Throwable { char[] p = new BufferedReader(new FileReader(a[1])).readLine().toCharArray(); char[] t = new BufferedReader(new FileReader(a[0])).readLine().toCharArray(); int u = t.length; int k = 0; for (int i = 0; i < u; i++) { new FileOutputStream (a[0]).write((char) ((int) t[i] ^ (int) p[k])); k = k = ++k % p.length; } } }

Valió la pena intentarlo. Sin embargo, no creo que Java sea el mejor lenguaje aquí ...


Java, 319 313 310 caracteres

  • Actualización 1: reemplazado char[]c=r(a[0]);char[]k=r(a[1]); por char[]c=r(a[0]),k=r(a[1]); , guardado 6 caracteres.

  • Actualización 2: reemplazada for(int i=0;i<c.length;c[i]^=k[i++%k.length]); por int i=0;for(char p:c)c[i]^=k[i++%k.length]; , guardado 3 caracteres.

import java.io.*;class X{public static void main(String[]a)throws Exception{char[]c=r(a[0]),k=r(a[1]);int i=0;for(char p:c)c[i]^=k[i++%k.length];Writer w=new FileWriter(a[0]);w.write(c);w.close();}static char[]r(String a)throws Exception{return new BufferedReader(new FileReader(a)).readLine().toCharArray();}}

Versión más legible:

import java.io.*; class X{ public static void main(String[]a)throws Exception{ char[]c=r(a[0]),k=r(a[1]);int i=0;for(char p:c)c[i]^=k[i++%k.length]; Writer w=new FileWriter(a[0]);w.write(c);w.close(); } static char[]r(String a)throws Exception{ return new BufferedReader(new FileReader(a)).readLine().toCharArray(); } }

Java IO es bastante detallado. Refactorizando dos lecturas de archivo a char [] en un método guardado 4 caracteres. Sí, cerrar (enjuagar) al escritor es absolutamente necesario. De lo contrario, el archivo se deja en blanco. De lo contrario, habría sido 298 292 289 caracteres.


PHP, 142 141 caracteres

Edit 1: fputs() lugar de fwrite() .

$t=fopen($argv[1],''r+'');$s=fgets($t);rewind($t);$k=fgets(fopen($argv[2],''r''));for($i=0;$i<strlen($s);$i++)fputs($t,$s{$i}^$k{$i%strlen($k)});

Bonita impresión:

$t = fopen($argv[1],''r+''); $s = fgets($t); rewind($t); $k = fgets(fopen($argv[2],''r'')); for($i=0; $i<strlen($s); $i++) fputs($t, $s{$i} ^ $k{$i % strlen($k)});


Perl, 40 caracteres

Es un poco frágil.

print$/=!1,($_=<>)^substr<>x 1E4,0,y///c

Perl tiene un operador de cadena xor incorporado. Para resolver este problema, la parte difícil es lograr que las dos cuerdas tengan la misma longitud.

$/=!1

Establece el "separador de registros" en el valor indefinido y no hace que se imprima nada. Con esta configuración, el operador de línea de lectura sorbirá en un archivo completo.

$_=<>

Carga todo el primer archivo (que contiene el mensaje) en la variable $_ .

substr <> x 1E4, 0, y///c

Crea otra cadena del segundo archivo (la clave) y la agrega a sí misma 10.000 veces. Afortunadamente, (1) esta cadena realmente larga será más larga que la cadena de mensaje, y (2) no será tan larga que hará que el programa se quede sin memoria (así es como esta solución es frágil). y///c es una operación para contar el número de caracteres en $_ , y es un carácter más corto que decir length . Esto acorta la cadena clave al mismo tamaño que la cadena del mensaje.


Python - 127 caracteres

utiliza parámetros de línea de comando para el archivo de clave y el archivo de datos

import sys a=sys.argv _,k,t=[open(x).read()for x in a] s=open(a[2],"w").write [s(chr(ord(x)^ord(y)))for x,y in zip(k*len(t),t)]

escribiendo en stdout - 109 caracteres

import sys _,k,t=[open(x).read()for x in sys.argv] print"".join(chr(ord(x)^ord(y))for x,y in zip(k*len(t),t))


Python3 - 114 caracteres

toma los parámetros de stdin

a=input().split() k,t=[open(x,"rb").read()for x in a] open(a[1],"wb").write(bytes(x^y for x,y in zip(k*len(t),t)))


q, 88 char

Implementado usando q desde http://kx.com/ que es un lenguaje escrito por Arthur Whitney e inspirado en APL y lisp.

a[0]1:"x"$2 sv''{(x|y)&not x&y}.''0b vs''''flip{y:count[x]#y;(x;y)}.(read1'')a:(hsym'')`$''.z.x

Así que una pequeña explicación de lo que está sucediendo: (leer de derecha a izquierda)

a:(hsym'')`$''.z.x

Crea una lista de dos identificadores de archivo de una lista de argumentos de tiempo de ejecución y los guarda para su uso posterior en la variable "a".

(read1'')

Pasa el cursor por los dos archivos, léelos y devuelve una lista de bytes donde byte = 0x00..0xFF ((22 bytes), (10 bytes))

{y:count[x]#y;(x;y)}.

Forme la clave a la misma longitud que el mensaje. La clave se trunca si es demasiado larga y se repite si es demasiado corta. La lista ahora está bien formateada, 2x22.

flip

Transponer la lista y ahora es 22x2.

0b vs''''

Convierta cada elemento de la lista en tipo binario

{(x|y)&not x&y}.''

El par XOR en todos los 22 elementos, devuelve una lista de 8 booleanos

"x"$2 sv''

Convierte 8 bits booleanos a byte.

a[0]1:

Escribir archivo, anulando el archivo de mensaje original.

Muestra de ejecución:

$ cp message.txt message.txt.bk $ q g.q message.txt key.txt $ diff -s message.txt message.txt.bk0 Binary files message.txt and message.txt.bk0 differ $ q g.q message.txt key.txt $ diff -s message.txt message.txt.bk0 Files message.txt and message.txt.bk0 are identical


Otro

Solución Perl, 59 (42) caracteres

(Conforme un trazador de líneas que parece funcionar hasta ahora :)

Programa (59 caracteres) con longitud de clave calculada:

$.-1?$_^=substr($k x((length)/length($k)+1),0,length):$k=$_

serán 42 caracteres si se usa el enfoque "frágil" de mobrule para la longitud de la clave:

$.-1?$_^=substr($k x 1e4,0,(length)):$k=$_

Línea de comando:

$> perl -i -0777 -pe''<insert above>'' keyfile messagefile

Esto reescribirá el mensaje en su forma xor-ed y volverá a su forma de texto claro:

$> cat keyfile ; cat messagefile Code Golf is Cool

Aplicar comando:

$> perl -i.bak -0777 -pe''<insert above>'' keyfile messagefile $> cat keyfile ; cat messagefile Code Golf ^P^[^E^FK^H^Y ^Tl/^@^SEI4O/ e/e

Aplicar de nuevo:

$> perl -i.bak -0777 -pe''<insert above>'' keyfile messagefile $> cat keyfile ; cat messagefile Code Golf is Cool

Saludos

rbo


C # 190 caracteres

using System.IO;class a{static void Main(string[] b){var c=File.ReadAllBytes(b[0]);var d=File.ReadAllBytes(b[1]);for(int e=0;e<c.Length;e++) c[e]^=d[e%d.Length];File.WriteAllBytes(b[0],c);}}


C #, 168:

using System.IO;class a{static void Main(string[] b){File.WriteAllBytes(b[0],File.ReadAllBytes(b[0]).Select((x,i)=>x^File.ReadAllBytes(b[1])[i%d.Length]).ToArray());}}

Una solución funcional. Guardé variables al subrayar la operación de lectura que hace que se ejecute una y otra vez.


Java - 306 Chars

Usando la solución Java de BalusC como base:

import java.io.*;class X{public static void main(String[]a)throws Exception{final char[]c=r(a[0]),k=r(a[1]);int i=0;for(int p:c)c[i]^=k[i++%k.length];new FileWriter(a[0]){{write(c);}}.close();}static char[]r(String a)throws Exception{return new BufferedReader(new FileReader(a)).readLine().toCharArray();}}

Más legible

import java.io.*; class X{ public static void main(String[]a)throws Exception{ final char[]c=r(a[0]),k=r(a[1]);int i=0;for(int p:c)c[i]^=k[i++%k.length]; new FileWriter(a[0]){{write(c);}}.close(); } static char[]r(String a)throws Exception{ return new BufferedReader(new FileReader(a)).readLine().toCharArray(); } }

En realidad, no probé el código, pero tampoco cambié nada drástico.


Python, 154 caracteres

import sys,struct;_,f,k=sys.argv open(f,''r+b'').write(''''.join(struct.pack(''B'',ord(a)^ord(b))for a,b in zip(open(f,''r+b'').read(),open(k,''rb'').read()*1000)))


Python, 162 caracteres

m,r,o=map,raw_input,open a,b=r(),r() t,k=m(lambda x:list(o(x).read()[:-1]),[a,b]) o(a,''w'').write(''''.join(m(chr,m(lambda c:ord(c[0])^ord(c[1]),zip(t,len(t)*k)))))

Python 3, 143 caracteres

i,o=input,open a,b=i(),i() t,k=map(lambda x:list(o(x,''rb'').read()[:-1]),[a,b]) o(a,''wb'').write(bytes(map(lambda c:c[0]^c[1],zip(t,len(t)*k))))


Ruby 72 62 caracteres

$<.inject{|k,l|l.each_byte{|b|$><<(b^(r=k.slice!0)).chr;k<<r}}

Podría guardar 10 caracteres si no tuviera que quitar un /n de la tecla de entrada con k=a.chomp; Se adelantó y lo hizo

Limitaciones: solo maneja claves de una sola línea.

Cómo funciona:

$< actúa como una matriz que contiene todas las líneas de todos los archivos de entrada.

.inject itera sobre la matriz,

{|k,l| : en la primera pasada, los argumentos son la línea clave, y la primera línea de la entrada.

l.each_byte{|b| toma cada carácter de las líneas de entrada como un int.

$><< significa "imprimir"

(b^(rkslice!0) XORs ''b'' con el primer caracter de la clave (que corta y almacena en ''r''

.chr; convierte el entero a ASCII

k<<r rota el primer carácter de la clave hasta el final.

}} El bloque produce la k actualizada, que se usará como primer argumento en la siguiente pasada para inyectar; el segundo argumento será la siguiente línea de entrada.