代码高尔夫:XORencryption
来自 :Encryption Co.
要 :x $ * sj4(就是你)
你的任务,如果你select接受它,就是用最短的击键次数创build一个程序
-
接受两个文件名参数(命令行或标准input),第一个是包含密钥和第二个消息的文件。 这两个文件将是纯文本。
-
使用XORencryption将密钥应用于消息,覆盖该文件。
例:
input文件:
StackOverflow很酷
键:
代码高尔夫
encryption输出文件的hex转储:
0000000: 101b 0506 4b08 1909 1425 030b 1200 2e1c ....K....%...... 0000010: 4c25 2c00 080d 0a L%,....
为了简单起见,假定文件可以放在内存中
此消息将自我encryption在5 … 4 … 3 … 2 … 1 …
##### #### _\_ ________ ##=-[.].]| \ \ #( _\ | |------| # __| | |||||||| \ _/ | |||||||| .--'--'-. | | ____ | / __ `|__|[o__o]| _(____nm_______ /____\____
如果密钥的大小大于或等于消息的大小,并且密钥由无偏的随机过程生成,则XORencryption不可能破解。 请参阅: 一次性垫 。 所以这里没有“糟糕的encryption”。
悔改, 13 7个字符(没有文件支持),14个字符(有文件支持)
Repent是我自己的一个深奥的基于堆栈的玩具语言,灵感来自J,APL,Golfscript和Python。 这是一个简短的解决scheme。 我会解释一下,但是已经很晚了,而且这是我的头脑,所以我会解释它,并在早上释放一个Silverlight解释器。
↓↷¦*⊕;€
说明:
↓ 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.
使用像:
Repent "↓↷¦*⊕;€" "Code Golf" "StackOverflow is Cool" > output.txt
输出(大多数字符不显示):
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
使用文件是:
↓↶▲⇄▲↓3↔⇄¦*⊕;▼
语言参考(未完成)
口译员(未完成)
Perl,40个字符
这有点脆弱。
print$/=!1,($_=<>)^substr<>x 1E4,0,y///c
Perl有一个内置的string异或运算符。 为了解决这个问题,困难的部分是让两个string具有相同的长度。
$/=!1
将“logging分隔符”设置为未定义的值,并不会导致打印任何内容。 使用此设置,文件readline运算符将在整个文件中啜泣。
$_=<>
将整个第一个文件(包含消息)加载到variables$_
。
substr <> x 1E4, 0, y///c
从第二个文件(键)创build另一个string,并将其自身添加到10,000次。 希望(1)这个真正长的string比消息string长,(2)不会太长,导致程序内存不足(这就是这个解决scheme是脆弱的)。 y///c
是计算$_
中字符个数的操作,它比说length
短一个字符。 这将密钥string缩短为与消息string相同的大小。
C#190个字符
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);}}
Python,162个字符
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个字符
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))))
GolfScript,28个字符
n.+/~:k;.,.)k.,@\/)*<{\(@^}%
要使用,传递消息文件,然后传递一个新行,然后将密钥文件传递给脚本的标准input:
$ (cat message-file ; echo ; cat key-file) | ruby golfscript.rb poorencrypt.gs
$(回声StackOverflow很酷;回声;回声代码高尔夫)| \ ruby golfscript.rb poorencrypt.gs>编码文件 $(猫编码文件;回声;回声代码高尔夫)| ruby golfscript.rb poorencrypt.gs StackOverflow很酷
Java, 319 313 310字符
-
更新1:replace
char[]c=r(a[0]);char[]k=r(a[1]);
由char[]c=r(a[0]),k=r(a[1]);
,保存了6个字符。 -
更新2:replace
for(int i=0;i<c.length;c[i]^=k[i++%k.length]);
通过int i=0;for(char p:c)c[i]^=k[i++%k.length];
,保存了3个字符。
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();}}
更可读的版本:
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相当详细。 重构两个文件到char []读取到一个方法保存4个字符。 是的,closures(冲洗)作者是绝对必要的。 否则该文件留空。 否则本来是298 292 289个字符。
Python3 – 114个字符
从标准input参数
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)))
F#,168个字符
open System.IO [<EntryPoint>] let main a= let k=File.ReadAllBytes a.[1] let ziv=v^^^k.[i%k.Length] File.WriteAllBytes(a.[0], Array.mapi z (File.ReadAllBytes a.[0])) 0
注:大多数IO,关键是Array.mapi。 此外,一些F#Guru可能会打败这个解决scheme – 我是一个C#程序员的交易,从来没有使用F#除了学习的乐趣。
Ruby 72 62个字符
$<.inject{|k,l|l.each_byte{|b|$><<(b^(r=k.slice!0)).chr;k<<r}}
我可以保存10个字符,如果我不必从input键中删除 走在前面,做到了 \n
, k=a.chomp;
限制:只能处理单行键。
怎么运行的:
$<
就像包含所有input文件的所有行一样的数组。
.inject
遍历数组,
{|k,l|
:在第一遍时,参数是关键线,并且是input的第一行。
l.each_byte{|b|
将input行中的每个字符作为int。
$><<
表示“打印”
(b^(rkslice!0)
与键中的第一个字符“异或”(将其切下并存储在“r”
.chr;
将整数转换回ascii
k<<r
将键的第一个字符旋转到最后。
}}
块生成更新后的k,它将在下一次传递中用作第一个参数注入; 第二个参数将是下一行input。
另一个
Perl解决scheme,59(42)个字符
(符合似乎工作到目前为止的一个class轮:)
计算密钥长度的程序(59个字符):
$.-1?$_^=substr($kx((length)/length($k)+1),0,length):$k=$_
如果使用密码长度为“脆弱”的方法 ,将会是42个字符:
$.-1?$_^=substr($kx 1e4,0,(length)):$k=$_
命令行:
$> perl -i -0777 -pe'<insert above>' keyfile messagefile
这将重写消息到它的异或forms,并回到它的明文forms:
$> cat keyfile ; cat messagefile Code Golf StackOverflow is Cool
应用命令:
$> perl -i.bak -0777 -pe'<insert above>' keyfile messagefile $> cat keyfile ; cat messagefile Code Golf ^P^[^E^FK^H^Y ^Tl/^@^SEI4O/ e/e
再次申请:
$> perl -i.bak -0777 -pe'<insert above>' keyfile messagefile $> cat keyfile ; cat messagefile Code Golf StackOverflow is Cool
问候
RBO
Haskell,181个字符
在Haskell打高尔夫时,I / O是个婊子,而二进制I / O则是双重的。 这个解决scheme可能会大大改善。 随意!
import Data.Bits import Data.ByteString as B u=unpack go[l,n]=o$pack$Prelude.zipWith xor(un)(cycle$ul) fx=mapM B.readFile x>>=g(B.writeFile$x!!1) main=Prelude.getLine>>=f.words
用法:
$ ghc --make encrypt.hs $ echo -n 'Code Golf' > key $ echo -n 'StackOverflow is Cool' > message $ echo 'key message' | ./encrypt $ od -tx1 message
PowerShell, 125 115个字符
到目前为止,这似乎是最短的基于networking的答案:
$k=[char[]](gc $args[1]);$i=0;sc $args[0] ([byte[]]([char[]](gc $args[0])|%{$_ -bXor $k[$i++%$k.Length]})) -en byte
漂亮的版本与命令缩写拼写出来:
$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
用法: powershell codegolf.ps1 message.txt key.txt
。 根据要求,它会覆盖message.txt
。
88个字符
使用http://kx.com/中的q实现,这是Arthur Whitney编写的一种语言,受APL和lisp的启发。
a[0]1:"x"$2 sv'{(x|y)¬ x&y}.'0b vs''flip{y:count[x]#y;(x;y)}.(read1')a:(hsym')`$'.zx
因此,对正在发生的事情作一点解释:(从右到左)
a:(hsym')`$'.zx
从运行时参数列表创build两个文件句柄的列表,并将其保存以便稍后在variables“a”中使用。
(read1')
循环两个文件,读取它们并返回字节列表,其中字节= 0x00..0xFF((22字节),(10字节))
{y:count[x]#y;(x;y)}.
将密钥形成与消息相同的长度。 如果太长,则会将其截断,如果太短则会重复。 该列performance在格式化很好,2 x 22。
flip
调换列表,现在是22×2。
0b vs''
将列表中的每个元素转换为二进制types
{(x|y)¬ x&y}.'
在所有22个元素中XOR配对明智,返回一个8布尔列表的列表
"x"$2 sv'
将8个布尔位转换为字节。
a[0]1:
写入文件,覆盖原来的消息文件。
样品运行:
$ cp message.txt message.txt.bk $ q gq message.txt key.txt $ diff -s message.txt message.txt.bk0 Binary files message.txt and message.txt.bk0 differ $ q gq message.txt key.txt $ diff -s message.txt message.txt.bk0 Files message.txt and message.txt.bk0 are identical
ruby – 158个字符
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)}}
漂亮的版本:
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) } }
该解决scheme利用了以下方面的问题:
你的任务,如果你select接受它,是创build一个程序在最短的击键次数 …
此解决scheme是使用手写识别input写在我的平板电脑上的。 在创build这个代码时没有任何键被触动。 因此,这个程序是在零击键中开发的。 游戏结束,我赢了!
Python – 127个字符
使用密钥文件和数据文件的命令行参数
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)]
写入标准输出 – 109个字符
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))
Java, 336 316 405个字符
编辑:忘了它必须从文件中读取。 *叹
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; } } }
值得一试。 不过,我不认为Java是这里最好的语言…
F#, 147 146个字符
这主要是基于driis的解决scheme 。 我所做的只是添加必要的缩进,以便编译,切换命令行参数的顺序,并收紧。 尽pipe如此,如果它能缩短一点,我也不会感到惊讶。 注意:您会收到关于不完整模式匹配的警告。 通常我会第一个抱怨,但我认为代码高尔夫应该是一个例外,通常的最佳做法。 🙂
open System.IO[<EntryPoint>]let m[|a;b|]=File.ReadAllBytes|>fun r->ra|>fun k->File.WriteAllBytes(b,Array.mapi(fun i->(^^^)k.[i%k.Length])(rb));0
F#,147个字符,更具可读性
open System.IO let r=File.ReadAllBytes [<EntryPoint>] let m[|a;b|]= let k=ra File.WriteAllBytes(b,Array.mapi(fun i->(^^^)k.[i%k.Length])(rb));0
PHP, 142 141个字符
编辑1: fputs()
而不是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)});
漂亮的打印:
$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)});
KSH93 – 152个字符
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
Python,154个字符
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)))
Java – 306个字符
以BalusC的Java解决scheme为基础:
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();}}
更可读:
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(); } }
我没有真正testing代码,但我也没有改变任何激烈的。
C – 163 161个字符
增加了刷新并删除了不必要的查找
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;}}
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; } }
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());}}
function性解决scheme 我通过内联读取操作来保存variables,从而导致它被反复执行。