Code Golf: cryptage XOR

À Partir De : Chiffrement Co.

À : x$*sj4 (c'est vous)

Votre mission, si vous l'acceptez, est de créer un programme dans les plus brefs nombre de frappes

  • prend deux paramètres de nom de fichier (soit ligne de commande ou stdin), le premier est un fichier contenant la clé et le second un message. Les deux fichiers seront en texte clair.

  • Applique la clé du message à l'aide de cryptage XOR , en écrasant le fichier.

exemple:

Fichier D'Entrée:

StackOverflow, c'est Cool

clé:

Code Golf

Hex vidage du cryptage de fichier de Sortie:

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

par souci de simplicité, supposons que les fichiers peuvent être stockés en mémoire


ce message sera auto-chiffré en 5... 4... 3... 2... 1...

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

Cryptage XOR est impossible à casser, si la taille de la clé est supérieure ou égale à la taille du message et la clé est générée par l'impartialité du processus aléatoire. Voir: unique plaquette . Donc pas de" mauvais cryptage " ici.

37
demandé sur Wayne Werner 2010-08-13 20:41:19

23 réponses

Repent", 13 7 chars (sans support de fichier), 14 char (avec support de fichier)

Repent est un langage jouet ésotérique basé sur la pile, inspiré de J, APL, Golfscript et Python. Voici un court de solution. Je vais l'expliquer, mais il est très tard et ça me fait réfléchir, donc je vais l'expliquer et libérer un interprète de Silverlight dans la matinée.

↓↷¦*⊕;€

explication:

↓     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.

utiliser comme:

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

sortie (la plupart des caractères ne s'affichent pas):

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

L'utilisation de fichiers est:

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

référence de langue (inachevée)

Interprète (inachevé)

25
répondu Callum Rogers 2010-08-18 23:14:53

Perl, 40 char

c'est un peu fragile.

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

Perl dispose d'un opérateur XOR string intégré. Pour résoudre ce problème, la partie la plus difficile est d'obtenir les deux chaînes ont la même longueur.

$/=!1

définit le "séparateur d'enregistrement" à la valeur non définie, et ne fait pas imprimer quoi que ce soit. Avec ce paramètre, le fichier readline opérateur puisent dans un fichier entier.

$_=<>

charge la totalité du premier fichier (contenant le message) dans la variable $_ .

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

crée une autre chaîne du second fichier (la clé) et l'ajoute à lui-même 10 000 fois. Avec un peu de Chance, (1) cette chaîne vraiment longue sera plus longue que la chaîne de messages, et (2) elle ne sera pas si longue qu'elle fera sortir le programme de la mémoire (c'est comme ça que cette solution est fragile). y///c est une opération pour compter le nombre de caractères $_ , et c'est un caractère plus court que length . Cela raccourcit la chaîne de caractères de la même taille que la chaîne de messages.

22
répondu mob 2010-08-14 03:01:23

C# 190 caractères

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);}}
12
répondu Jeffrey L Whitledge 2010-08-13 17:37:17

Python, 162 caractères

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 caractères

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))))
8
répondu Federico A. Ramponi 2010-08-13 19:49:27

GolfScript, 28 char

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

pour utiliser, passer le fichier message, Suivi d'une nouvelle ligne, suivi du fichier clé à l'entrée standard du script:

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

$ (echo StackOverflow 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
StackOverflow is Cool
8
répondu mob 2010-08-13 20:42:34

Java, 319 313 310 chars


  • Maj 1: remplacé char[]c=r(a[0]);char[]k=r(a[1]); par char[]c=r(a[0]),k=r(a[1]); , enregistré 6 caractères.

  • mise à jour 2: remplacé for(int i=0;i<c.length;c[i]^=k[i++%k.length]); par int i=0;for(char p:c)c[i]^=k[i++%k.length]; , enregistré 3 caractères.


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();}}

version plus lisible:

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 est assez bavard. Refactoring deux fichiers-to-char[] lit dans une méthode sauvée 4 caractères. Oui, fermer (flushing) l'écrivain est absolument nécessaire. Sinon le fichier est vide. Cela aurait été 298 292 289 jars.

7
répondu BalusC 2010-08-16 11:31:33

Python3 - 114 caractères

prend les paramètres 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)))
6
répondu John La Rooy 2010-08-14 07:37:06

F#, 168 caractères

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

Note: la plupart du temps IO, la clé est Array.mapi. En outre, certains F # Guru battra probablement l'enfer hors de cette solution - je suis un programmeur C# par le commerce, et jamais utilisé F# pour autre chose que d'apprendre pour le plaisir.

4
répondu driis 2010-08-13 17:44:51

Ruby 72 62 chars

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

je pourrais sauver 10 chars si je n'avais pas à rayer un \n de la clé de saisie avec k=a.chomp; " est allé de l'avant et l'a fait

Limitations: ne traite que les touches à une seule ligne.

Comment cela fonctionne:

$< agit comme un tableau contenant toutes les lignes de tous les fichiers d'entrée.

.inject parcourt le tableau,

{|k,l| : au premier passage, les arguments sont la ligne de touche, et la première ligne de l'entrée.

l.each_byte{|b| prend chaque caractère des lignes d'entrée comme int.

$><< signifie "imprimer"

(b^(r.k.slice!0) XORs 'b' avec le premier caractère de la clé (qui il découpe et stocke en "r

.chr; convertit l'entier en ascii

k<<r fait tourner le premier caractère de la clé jusqu'au bout.

}} le bloc fournit le k mis à jour, qui sera utilisé comme premier argument dans le passage suivant pour injecter; le deuxième argument sera la ligne suivante d'entrée.

4
répondu AShelly 2010-08-14 06:21:15

un autre

Perl solution, 59 (42) jars

(conforme one-liner qui semble fonctionner jusqu'à présent:)

programme (59 caractères) Avec longueur de clé calculée:

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

sera de 42 caractères si vous utilisez mobrule "fragile" approche à la longueur de la clé:

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

Ligne De Commande:

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

ce sera réécrire le message à sa forme xor-ed et retour à sa forme de texte clair:

 $> cat keyfile ; cat messagefile

 Code Golf
 StackOverflow is Cool

appliquer la commande:

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

 Code Golf
 ^P^[^E^FK^H^Y   ^Tl/^@^SEI4O/   e/e

appliquer de nouveau:

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

 Code Golf
 StackOverflow is Cool

concerne

rbo

4
répondu rubber boots 2017-05-23 11:45:39

Haskell, 181 caractères

I/O est une chienne quand le golf en Haskell, et binaire I/O doublement. Cette solution peut probablement être grandement améliorée. N'hésitez pas!

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

Utilisation:

$ ghc --make encrypt.hs
$ echo -n 'Code Golf' > key
$ echo -n 'StackOverflow is Cool' > message
$ echo 'key message' | ./encrypt
$ od -tx1 message
3
répondu Thomas 2010-08-13 21:24:36

PowerShell, 125 115 chars

Jusqu'à présent, cela semble être la réponse la plus courte. basée sur le net:

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

Jolie version avec commande abréviations écrit:

$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

Utilisation: powershell codegolf.ps1 message.txt key.txt . Comme demandé, il écrira message.txt .

3
répondu Heinzi 2010-08-14 13:52:43

q, 88 char

mis en œuvre en utilisant q de http://kx.com / qui est un langage écrit par Arthur Whitney et inspiré par APL et lisp.

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

Donc une petite explication de ce qui se passe: (lire de Droite à Gauche)

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

crée une liste de deux poignées de fichiers à partir d'une liste d'arguments runtime et la sauve pour une utilisation ultérieure dans la variable"a".

(read1')

Boucle les deux fichiers, lisez - les et retournez une liste d'octets où byte=0x00..0xFF ((22 octets), (10 octets))

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

modeler la clé à la même longueur que le message. La clé est tronquée si elle est trop longue et répétée si trop court. La liste est maintenant bien formatée, 2x22.

flip

Transpose la liste et c'est maintenant 22x2.

0b vs''

Convertissez chaque élément de la liste en type binaire

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

XOR pair wise across all 22 elements, renvoie une liste de 8 booléens

"x" sv'

Convertissez 8 bits booléens en octet.

a[0]1:

Écrire le fichier, pour ignorer le message d'origine du fichier.

Exemple:

$ 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
3
répondu md0 2010-08-14 17:01:55

Ruby - 158 caractères

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)}}

version plus jolie:

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)
    }
}

cette solution tire profit de l'aspect suivant du problème:

votre mission, si vous choisissez l'accepter, c'est pour créer un programme de le nombre le plus court de touches que...

Cette solution a été écrite sur ma tablette en utilisant l'écriture reconnaissance de la contribution. Aucune clé n'a été caressée lors de la création de ce code. Par conséquent, ce programme a été mis au point avec zéro frappes. Game over, j'ai gagné!

2
répondu bta 2010-08-13 22:47:22

Python - 127 caractères

utilise les paramètres de ligne de commande pour le fichier-clé et le fichier de données

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)]

écrit sur la sortie standard - 109 caractères

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))
2
répondu gnibbler 2010-08-14 07:21:33

Java , 336 316 405 chars

EDIT: vous avez Oublié qu'il avait à lire à partir d'un fichier. * sigh

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;
    }
}
}

ça valait le coup d'essayer. Cependant, Je ne pense pas que Java soit le meilleur langage ici...

1
répondu TheLQ 2010-08-14 03:44:19

F#, 147 146 caractères

C'est fortement basé sur les driis la solution . J'ai tout ajouter le nécessaire indentation donc compilé, changé l'ordre des paramètres de ligne de commande, et resserré les choses en place. Je ne serais pas surpris si elle peut encore être raccourcie un peu, cependant. Note: vous recevrez un avertissement concernant les correspondances incomplètes. Normalement, je serais le premier à me plaindre, mais je pense code golf mérite une exception aux bonnes pratiques habituelles. :)

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 caractères, plus lisible

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
0
répondu bcat 2017-05-23 12:16:55

PHP, 142 141 characters

Edit 1: fputs() au lieu 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)});

Pretty print:

$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)});
0
répondu 2 revsuser113292 2010-08-14 01:47:26

KSH93-152 chars

m=$(<)
k=$(<)
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 >
0
répondu fpmurphy1 2010-08-14 18:04:30

Python, 154 caractères

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)))
0
répondu hb2pencil 2010-08-20 17:29:55

Java-306 Chars

utilisant la solution Java de BalusC comme 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();}}

plus lisible:

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();
 }
}

Je n'ai pas vraiment testé le code, mais je n'ai rien changé non plus.

0
répondu Andy 2010-08-20 17:40:56

C - 163 161 chars

ajouté flush et supprimé inutile seek.

ont joué au golf:

#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;}}

ungolfed:

#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;
    }
}
0
répondu 3 revsuser295190 2010-12-08 21:47:00

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());}}

une solution fonctionnelle. j'ai enregistré des variables en inclinant l'opération de lecture qui fait qu'elle soit exécutée encore et encore.

0
répondu usr 2012-04-11 23:28:16