代码高尔夫:异或加密

37

来自: 加密公司。
: x$*sj4(即你)

如果您愿意接受任务,您需要用最少的按键数创建一个程序,该程序:

  • 接受两个文件名参数(可以是命令行或标准输入),第一个文件包含密钥,第二个文件包含一些消息。这两个文件都是纯文本。

  • 使用XOR加密将密钥应用于消息,覆盖原始文件。

示例:

输入文件:

StackOverflow is Cool

密钥:

Code Golf

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

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

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


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

     #####
    #### _\_  ________
    ##=-[.].]| \      \
    #(    _\ |  |------|
     #   __| |  ||||||||
      \  _/  |  ||||||||
   .--'--'-. |  | ____ |
  / __      `|__|[o__o]|
_(____nm_______ /____\____ 
如果密钥的大小大于或等于消息的大小,并且密钥是通过无偏随机过程生成的,则XOR加密是不可能被破解的。参见:一次性密码本。所以这里没有“差劲的加密”问题。

10
以下是雅虎通使用的加密对话算法。 - Brian
2
上述加密输出文件解密后为“StackOverflow is Coolh*”。 - Jeffrey L Whitledge
5
不,实际上在加密的文件末尾有一个\r\n对。所以很可能是原帖作者实现时出现了bug :) - Thomas
3
只要随机密钥大于消息本身,这实际上是一个很棒的算法。 - cobbal
4
...并且你绝不能重复使用密钥,而且在使用后必须销毁密钥,同时你需要能够管理密钥分发。 - dmckee --- ex-moderator kitten
显示剩余10条评论
23个回答

0

Java - 306个字符

以BalusC的Java解决方案为基础:

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

我实际上没有测试这段代码,但我也没有做出任何重大的更改。


0

C - 163 161 字符

添加了 flush 并删除了不必要的 seek。

压缩版:

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

未压缩:

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

你可以使用,运算符和?:来缩短代码: while(fgets(&l,2,f)) fseek(f,-1,1), putc(l^*k++,f), fflush(f), !*k?k=p:0; 节省3个字符。 - flownt

0

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

一个功能性的解决方案。我通过内联读取操作来保存变量,这会导致它被反复执行。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接