Подтвердить что ты не робот

Code Golf: шифрование XOR

От: Encryption Co.
Кому: x $* sj4 (что вы)

Ваша миссия, если вы решите ее принять, заключается в создании программы в кратчайшем количестве нажатий клавиш, которые

  • Принимает два параметра имени файла (либо командной строки, либо stdin), первый - это файл, содержащий ключ, а второй - некоторое сообщение. Оба файла будут иметь простой текст.

  • Применяет ключ к сообщению с помощью XOR encryption, перезаписывая файл.

Пример:

Входной файл:

StackOverflow is Cool

Key:

Код Гольф

Hex дамп файла с зашифрованным выходом:

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 Шифрование невозможно взломать, если размер ключа больше или равен размеру сообщения, а ключ генерируется непредвзятым случайным процессом. См.: Одноразовая панель. Таким образом, здесь нет "плохого шифрования".

4b9b3361

Ответ 1

Показывать, 13 7 символов (без поддержки файлов), 14 char (с поддержкой файлов)

Repent - это эзотерический игрушечный язык, основанный на стеках, с вдохновением от J, APL, Golfscript и Python. Вот короткое решение. Я объясню это, но очень поздно, и это делает мою голову, поэтому я объясню это и выпущу интерпретатор 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↔⇄¦*⊕;▼

Языковая ссылка (незавершенная)

Интерпретатор (незавершенный)

Ответ 2

Perl, 40 char

Это немного хрупкий.

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

Perl имеет встроенный оператор string xor. Чтобы решить эту проблему, жесткая часть получает две строки с одинаковой длиной.

$/=!1

Устанавливает "разделитель записи" в значение undefined и не вызывает печати ничего. С помощью этого параметра оператор readline файла будет разбит на весь файл.

$_=<>

Загружает весь первый файл (содержащий сообщение) в переменную $_.

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

Создает другую строку из второго файла (ключ) и добавляет ее к себе 10 000 раз. Надеемся, что (1) эта очень длинная строка будет длиннее строки сообщения, и (2) она не будет так долго, что это приведет к тому, что у программы закончится нехватка памяти (что, как это решение является хрупким). y///c - операция подсчета количества символов в $_, и это на один символ короче, чем length. Это сокращает строку ключа до того же размера, что и строка сообщения.

Ответ 3

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

Ответ 4

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

Ответ 5

GolfScript, 28 char

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

Чтобы использовать, передайте файл сообщения, за которым следует новая строка, а затем файл ключа со стандартным входом 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

Ответ 6

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

Более читаемая версия:

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 символа. Да, закрытие (промывка) писателя абсолютно необходимо. Кроме того, файл остается пустым. В противном случае было бы 298 292 289 символов.

Ответ 7

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

Ответ 8

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

Примечание. В основном IO ключом является Array.mapi. Кроме того, некоторые F # Guru, вероятно, выйдут из этого решения - я программист на С# по профессии и никогда не использовал F # для чего-либо еще, кроме обучения для удовольствия.

Ответ 9

Ruby 72 62 символа

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

Я мог бы сэкономить 10 символов, если мне не пришлось вырезать \n из входного ключа с k=a.chomp;, и он сделал это

Ограничения: обрабатываются только однострочные ключи.

Как это работает:

$< действует как массив, содержащий все строки всех входных файлов.

.inject выполняет итерацию по массиву,

{|k,l|: при первом проходе аргументами являются ключевая строка и первая строка ввода.

l.each_byte{|b| принимает каждый символ из входных строк как int.

$><< означает "печать"

(b^(r.k.slice!0) XORs 'b' с первым символом в ключе (который он срезает и сохраняет в 'r'

.chr; преобразует целое число обратно в ascii

k<<r вращает первый символ ключа до конца.

}} Блок дает обновленный k, который будет использоваться в качестве первого аргумента в следующем проходе для инъекции; второй аргумент будет следующей строкой ввода.

Ответ 10

Другой

Решение Perl, 59 (42) символов

(соответствует одному слою, который работает до сих пор:)

Программа (59 символов) с вычисленной длиной ключа:

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

будет 42 символа при использовании mobrule 'хрупкого' подхода до длины ключа:

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

Командная строка:

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

Этот будет переписывать сообщение в его xor-ed-форму и обратно в текстовую форму:

 $> 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

Привет

БВУ

Ответ 11

Haskell, 181 символ

I/O - сука при игре в гольф в Haskell и двоичном вводе-выводе вдвойне. Возможно, это решение значительно улучшится. Не стесняйтесь!

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

Использование:

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

Ответ 12

PowerShell, 125 115 символов

До сих пор это, по-видимому, самый короткий ответ на основе .net:

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

Ответ 13

q, 88 char

Реализовано с помощью q из http://kx.com/, который является языком, написанным Артуром Уитни и вдохновленным APL и 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

Итак, немного объясним, что происходит: (читайте справа налево)

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

Создает список из двух дескрипторов файлов из списка аргументов времени выполнения и сохраняет их для последующего использования в переменной "a".

(read1')

Прокрутите два файла, прочитайте их и верните список списка байтов, где byte = 0x00..0xFF ((22 байта), (10 байт))

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

Настройте ключ на ту же длину, что и сообщение. Ключ усечен, если слишком длинный и повторяется, если слишком короткий. Список теперь хорошо отформатирован, 2x22.

flip

Переместите список и теперь 22x2.

0b vs''

Преобразование каждого элемента списка в двоичный тип

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

Параметр XOR по всем 22 элементам возвращает список из списка из 8 булевых

"x"$2 sv'

Преобразование 8 булевых битов в байты.

a[0]1:

Записать файл, отменив исходный файл сообщения.

Пример прогона:

$ 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

Ответ 14

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

Это решение использует следующий аспект проблемы:

Ваша миссия, если вы решите принять его, - создать программу в кратчайшее количество нажатий клавиш что...

Это решение было написано на моем планшете, используя распознавание рукописного ввода для ввода. При создании этого кода не было поглажено никаких клавиш. Поэтому эта программа была разработана с нулевыми нажатиями клавиш. Игра окончена, я побеждаю!

Ответ 15

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

запись в stdout - 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))

Ответ 16

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 - лучший язык здесь...

Ответ 17

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

Ответ 18

F #, 147 146 символов

Это в значительной степени основано на driis решении. Все, что я сделал, это добавить необходимый отступ, чтобы он скомпилировал, переключил порядок параметров командной строки и затянул все. Я бы не удивился, хотя его все же можно немного сократить. Примечание. Вы получите предупреждение о неполных совпадениях шаблонов. Обычно я был бы первым, кто пожаловался бы на это, но я думаю, что гольф для кодов заслуживает исключения из обычных лучших практик.:)

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 символов, более читаемый

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

Ответ 19

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

Ответ 20

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

Ответ 21

Java - 306 Chars

Использование решения 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();
 }
}

Я действительно не тестировал код, но я также ничего не изменил.

Ответ 22

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

Ответ 23

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

Функциональное решение. Я сохранил переменные, введя в действие операцию чтения, которая заставляет ее выполняться снова и снова.