Code Golf:XOR加密

Way*_*ner 37 encryption code-golf xor

来自:加密公司
收件人:x $*sj4(就是你)

如果您选择接受它,您的任务就是用最短的击键次数创建一个程序

  • 采用两个文件名参数(命令行或标准输入),第一个是包含密钥的文件,第二个是一些消息.这两个文件都是纯文本.

  • 使用XOR加密将密钥应用于邮件,覆盖文件.

例:

输入文件:

StackOverflow很酷

键:

Code Golf

加密输出文件的十六进制转储:

0000000: 101b 0506 4b08 1909 1425 030b 1200 2e1c  ....K....%......
0000010: 4c25 2c00 080d 0a                        L%,....
Run Code Online (Sandbox Code Playgroud)

为简单起见,假设文件可以适合内存


此消息将在5 ... 4 ... 3 ... 2 ... 1中自加密...

     #####
    #### _\_  ________
    ##=-[.].]| \      \
    #(    _\ |  |------|
     #   __| |  ||||||||
      \  _/  |  ||||||||
   .--'--'-. |  | ____ |
  / __      `|__|[o__o]|
_(____nm_______ /____\____ 
Run Code Online (Sandbox Code Playgroud)

如果密钥的大小大于或等于消息的大小并且密钥是由无偏的随机过程生成的,则XOR加密是不可能破解的.见:一次性垫.所以这里没有"糟糕的加密".

Cal*_*ers 25

悔改,13 7个字符(无文件支持),14个字符(有文件支持)

忏悔是我自己的一种基于堆栈的玩具语言,灵感来自J,APL,Golfscript和Python.这是一个简短的解决方案.我会解释它,但是已经很晚了,这是我的头脑,所以我会解释它并在早上发布Silverlight翻译.

??¦*?;€
Run Code Online (Sandbox Code Playgroud)

说明:

?     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.
Run Code Online (Sandbox Code Playgroud)

使用如下:

Repent "??¦*?;€" "Code Golf" "StackOverflow is Cool" > output.txt
Run Code Online (Sandbox Code Playgroud)

输出(大多数字符不显示):

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
Run Code Online (Sandbox Code Playgroud)

使用文件是:

??????3??¦*?;?
Run Code Online (Sandbox Code Playgroud)

语言参考(未完成)

口译员(未完成)

  • +1为我自己的'基于堆栈的玩具语言' (14认同)
  • 我想你可以用香蕉吗代替|||| ......没有人会理解:D (13认同)
  • @belisarius Bananas FTW! (4认同)

mob*_*mob 22

Perl,40 char

它有点脆弱.

print$/=!1,($_=<>)^substr<>x 1E4,0,y///c
Run Code Online (Sandbox Code Playgroud)

Perl有一个内置的字符串xor运算符.为了解决这个问题,困难的部分是使两个字符串具有相同的长度.

$/=!1
Run Code Online (Sandbox Code Playgroud)

将"记录分隔符"设置为未定义的值,并且不会导致打印任何内容.使用此设置,文件读取线操作符将覆盖整个文件.

$_=<>
Run Code Online (Sandbox Code Playgroud)

将整个第一个文件(包含消息)加载到变量中$_.

substr <> x 1E4, 0, y///c
Run Code Online (Sandbox Code Playgroud)

从第二个文件(密钥)中创建另一个字符串,并将其添加到自身10,000次.希望,(1)这个真正长的字符串将比消息字符串长,并且(2)它不会太长,导致程序耗尽内存(这就是这个解决方案的脆弱性).y///c是一个计算字符数的操作$_,它比说的短一个字符length.这会将密钥字符串缩短为与消息字符串相同的大小.

  • 该程序不符合规范,不会覆盖输入消息. (4认同)

Jef*_*dge 12

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);}}
Run Code Online (Sandbox Code Playgroud)


Fed*_*oni 8

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)))))
Run Code Online (Sandbox Code Playgroud)

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))))
Run Code Online (Sandbox Code Playgroud)


mob*_*mob 8

GolfScript,28个字符

n.+/~:k;.,.)k.,@\/)*<{\(@^}%
Run Code Online (Sandbox Code Playgroud)

要使用,请传递消息文件,然后是新行,然后将密钥文件传递给脚本的标准输入:

$ (cat message-file ; echo ; cat key-file) | ruby golfscript.rb poorencrypt.gs
Run Code Online (Sandbox Code Playgroud)
$ (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


Bal*_*usC 7

Java,319 313 310字符


  • 更新1:替换char[]c=r(a[0]);char[]k=r(a[1]);char[]c=r(a[0]),k=r(a[1]);,保存6个字符.

  • 更新2:替换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();}}
Run Code Online (Sandbox Code Playgroud)

更易阅读的版本:

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();
 }
}
Run Code Online (Sandbox Code Playgroud)

Java IO非常冗长.将两个file-to-char []读取重构为保存4个字符的方法.是的,关闭(刷新)作者是绝对必要的.否则文件留空.否则它将是298 292 289个字符.

  • +1用于在java中进行认真尝试.代码高尔夫球太少了 (3认同)

Joh*_*ooy 6

Python3 - 114个字符

从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)))
Run Code Online (Sandbox Code Playgroud)


dri*_*iis 4

F#,168 个字符

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
Run Code Online (Sandbox Code Playgroud)

注:主要是IO,关键是Array.mapi。另外,一些 F# 专家可能会彻底摆脱这个解决方案 - 我是一名 C# 程序员,除了学习乐趣之外,从未将 F# 用于其他任何用途。

  • @Brian,我认为(基于 2 分钟的谷歌搜索),声明 main 是获取命令行参数的最短方法?否则我必须调用Environment.GetCommandLineArgs,它总共有30 个字符。如果有更好的方法,请指正:-) (2认同)