Код Гольф: шифрование XOR

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

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

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

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

Пример:

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

StackOverflow - это круто

Ключ:

Код Гольф

Шестнадцатеричный дамп зашифрованного выходного файла:

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


person Community    schedule 13.08.2010    source источник
comment
Это алгоритм Yahoo! Messenger используется для шифрования разговоров.   -  person Brian    schedule 13.08.2010
comment
Зашифрованный выходной файл выше расшифровывается как StackOverflow - Coolh *.   -  person Jeffrey L Whitledge    schedule 13.08.2010
comment
Вероятно, это результат окончания строки \ r \ n в Windows.   -  person Wayne Werner    schedule 13.08.2010
comment
Нет, на самом деле в конце зашифрованного файла есть пара \r\n. Так что, вероятно, ошибка в реализации OP :)   -  person Thomas    schedule 14.08.2010
comment
На самом деле это отличный алгоритм, предполагающий, что случайный ключ больше, чем сообщение.   -  person cobbal    schedule 14.08.2010
comment
Плохое шифрование - неправильное название. Шифрование XOR невозможно, если размер ключа равен размеру сообщения или превышает его.   -  person NullUserException    schedule 14.08.2010
comment
Кстати, я сделал забавный проект, основанный на двух таблицах времени, назначение здесь: Сайт класса, Project PDF, зашифрованные тексты   -  person Lolindrath    schedule 14.08.2010
comment
Идеальная схема шифрования! Теперь все, что нам нужно сделать, это безопасно доставить случайный блокнот.   -  person Adrian Pronk    schedule 14.08.2010
comment
Кто будет делать APL версию? (возможно, менее 10 символов)   -  person Adrian Pronk    schedule 14.08.2010
comment
@NULL: ... и вы никогда не используете ключи повторно, и вы уничтожаете ключ после использования и вы может управлять распределением ключей ...   -  person dmckee --- ex-moderator kitten    schedule 15.08.2010
comment
Конечно, есть этот одноразовый блокнот, но плохое шифрование относится к тому факту, что если вы можете безопасно передать ключ, вы можете безопасно передавать данные, так зачем же шифрование?   -  person Wayne Werner    schedule 15.08.2010
comment
@Wayne: Потому что вы можете безопасно передавать данные только в течение очень короткого промежутка времени. Если вы знаете все свои сообщения заранее, вы можете просто отправить их прямо в течение этого времени, но если вы еще не знаете сообщения, вы все равно можете воспользоваться временной защитой, чтобы отправить достаточно длинный ключ, который вы можете позже используйте для отправки и получения зашифрованных сообщений после потери доступа к защищенному каналу.   -  person bcat    schedule 16.08.2010
comment
@bcat Если вы повторно используете такой ключ, вы делаете это неправильно. Вы предоставляете перехватчику больше информации, что снижает безопасность шифрования. Вы должны передать несколько ключей во время фазы безопасности и некоторую схему выбора между ними.   -  person Colin DeClue    schedule 16.08.2010
comment
@Colin: вы можете использовать шифр с одним блокнотом для отправки более одного сообщения, если общая длина сообщений меньше, чем общая длина шифра, и вы не используете повторно какую-либо часть шифра.   -  person Brian    schedule 17.08.2010
comment
@ Брайан: Ах да. Я не думал об этом.   -  person Colin DeClue    schedule 17.08.2010


Ответы (23)


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

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↔⇄¦*⊕;▼

Справочник по языку (незаконченный)

Переводчик (незаконченный)

person Community    schedule 14.08.2010
comment
Я не был тем, кто проголосовал против, но это могло быть потому, что ваше решение не выполняет файловый ввод-вывод. - person bcat; 14.08.2010
comment
Ой. Хорошо, тогда. Мне нужно добавить поддержку для этого :( - person Callum Rogers; 14.08.2010
comment
+1 за то, что вы придумали еще один извращенный собственный язык, который никто, кроме вас, не читает и не исполняет. ;) - person x4u; 14.08.2010
comment
Думаю, можно заменить ¦⇄¦⇄ на 香蕉 吗 ... тоже никто не поймет: D - person Dr. belisarius; 14.08.2010
comment
@Yi Jiang WoW! Вы говорите Покайтесь! : D - person Dr. belisarius; 14.08.2010
comment
Это все обоснованные жалобы, я полагаю, мне не стоит играть с ними, пока я не опубликую их. - person Callum Rogers; 14.08.2010
comment
@bel да у нас их нет! - person bmargulies; 14.08.2010
comment
... и, конечно же, игрушечный язык может тривиально решить любую задачу короче, чем общий язык: просто продолжайте специализироваться на языке, пока он не станет самым коротким! - person Eamon Nerbonne; 30.12.2010

Perl, 40 символов

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

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

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

$/=!1

Устанавливает «разделитель записей» на неопределенное значение и ничего не выводит на печать. С этой настройкой оператор строки чтения файла будет пролистывать весь файл.

$_=<>

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

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

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

person Community    schedule 13.08.2010
comment
Совершенно потрясающе. Не могли бы вы объяснить нам, невежественным по Perl? - person driis; 14.08.2010
comment
Эта программа не соответствует спецификациям, она не перезапишет входное сообщение. - person rubber boots; 14.08.2010

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);}}
person Community    schedule 13.08.2010
comment
Замечательно, по крайней мере, примерно на уровне кода Python. Впечатляет для многословных языков .Net. :) - person Russell; 14.08.2010

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))))
person Community    schedule 13.08.2010
comment
Эпично. У меня не было меньше 290 :( - person hb2pencil; 13.08.2010
comment
Понимание списка короче _1 _ / _ 2_. - person kennytm; 14.08.2010

GolfScript, 28 знаков

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

Чтобы использовать, передайте файл сообщения, а затем новую строку, а затем файл ключа в стандартный ввод сценария:

$ (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
person Community    schedule 13.08.2010
comment
Можно выполнять ввод-вывод файлов с помощью Golfscript. см. golf.shinh.org/reveal.rb?Remenber+Previous+Input / - person John La Rooy; 15.08.2010

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

person Community    schedule 14.08.2010
comment
+1 за серьезную попытку в java. в коде гольф слишком мало - person Sean Patrick Floyd; 15.08.2010
comment
мне удалось сохранить 3 символа ... измените for loop на int i=0;for(char p:c)c[i]^=k[i++%k.length]; - person st0le; 16.08.2010
comment
Я собирался закричать воровство, но вы придерживаетесь другого подхода. +1 - person TheLQ; 17.08.2010
comment
Я впечатлен тем, что у вас что-то вроде этого меньше 500 символов. Java довольно многословна. +1, конечно. - person Wayne Werner; 18.08.2010

Python3 - 114 символов

берет параметры из стандартного ввода

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)))
person Community    schedule 14.08.2010
comment
+1. Пока что ваше кажется самым коротким неэзотерическим решением, которое фактически соответствует спецификации (= перезапись входного файла). - person Heinzi; 14.08.2010

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

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

person Community    schedule 13.08.2010
comment
Вы можете избавиться от точки входа / main / 0 и просто оставить тело main как «код верхнего уровня», что является хорошей экономией кода для гольфа. - person Brian; 14.08.2010
comment
@Brian, я думаю (основываясь на двухминутном поиске в Google), что объявление main - это самый короткий способ получить параметры командной строки? В противном случае мне пришлось бы вызвать Environment.GetCommandLineArgs, что составляет целых 30 символов. Если есть способ получше, поправьте меня, пожалуйста :-) - person driis; 14.08.2010
comment
О, я пропустил это - прикосновение! - person Brian; 14.08.2010
comment
Выглядит неплохо, хотя я думаю, что вы поменяли аргументы командной строки. (Предполагается, что имя файла ключа следует перед именем файла сообщения.) Кроме того, вам потребуется некоторая идентификация (достаточно одного пробела) перед операторами в теле main. - person bcat; 14.08.2010

Рубин 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) XOR выполняет 'b' с первым символом в ключе (который он отсекает и сохраняет в 'r'

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

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

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

person Community    schedule 13.08.2010
comment
Так что не делай этого. Позвольте новой строке быть частью ключа или используйте файл ключа, который не заканчивается новой строкой. - person mob; 14.08.2010
comment
Объект ARGF - это добавление новой строки между двумя входными файлами. Я снимаю ее, чтобы она соответствовала образцу. Если это не требование, я буду рад сохранить 10 символов. - person AShelly; 14.08.2010
comment
Кроме того, это помещает вывод на стандартный вывод, вам нужна магия командной строки для замены ввода. Но если гольфскрипту это сойдет с рук, я не понимаю, почему рубин не может. - person AShelly; 14.08.2010
comment
$ ›‹< просто просит милое имя. - person Jordan Running; 17.08.2010

Другой

Решение 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

Это перепишет сообщение в его отредактированном виде и обратно в текстовую форму:

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

person Community    schedule 14.08.2010

Haskell, 181 символ

Ввод-вывод - это сука, когда играешь в гольф на 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
person Community    schedule 13.08.2010
comment
Разве вы не можете избавиться от некоторых символов, удалив префиксы Prelude? - person fuz; 24.08.2010
comment
@FUZxxl: Нет, эти функции конфликтуют с функциями с одинаковыми именами из Data.ByteString (который был разработан для квалифицированного импорта). Если я правильно помню, импорт только нужных функций оказался дольше. - person Thomas; 26.08.2010
comment
AFAIK, если вы импортировали их с префиксом, вы все равно можете вызывать функции Prelude без префикса, поэтому этот импорт префикса существует. (Я правда не уверен). - person fuz; 27.08.2010
comment
Вы так думаете, но, к сожалению, нет. По крайней мере, GHC 6.12.1 отвергает это как неоднозначное. - person Thomas; 27.08.2010

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.

person Community    schedule 14.08.2010
comment
Кратчайшее решение .NET, если вы не считаете IronPython, тогда вы можете использовать это;) - person Wayne Werner; 13.04.2012
comment
Спасибо Джованни за то, что он сообщил мне об ошибке по почте: это прерывается, если сообщение содержит разрыв строки, поскольку get-content в этом случае не вернет String. - person Heinzi; 06.12.2013

q, 88 символов

Реализовано с использованием q из http://kx.com/, языка, написанного Артуром Уитни и вдохновленного APL и шепелявить

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
person Community    schedule 14.08.2010

Рубин - 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)
    }
}

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

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

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

person Community    schedule 13.08.2010
comment
Здесь нужно сделать множество небольших улучшений: a=proc{|b|...} сохраняет 2 вместо def a(b);...;end. -2 для t,k=$*.map{|f|a(f)}. -1 для File.new вместо open. -2 за (t.size-1).times вместо upto ... - person AShelly; 14.08.2010
comment
И зачем вам писать "modulo против %"? - person AShelly; 14.08.2010

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))
person Community    schedule 14.08.2010

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

person Community    schedule 14.08.2010
comment
k = k = ++k % p.length; ?? почему бы не использовать это? k=(k+1)%p.length - person st0le; 14.08.2010
comment
Кроме того, похоже, что вы не используете u в нескольких местах, поэтому просто используйте t.length напрямую, что сэкономит некоторые символы. - person st0le; 14.08.2010
comment
for (int i=0; i < u; i++) { t[i]^=p[i%p.length]; } затем переместите write за пределы цикла, - person st0le; 14.08.2010
comment
Вы можете сократить int объявления до int u=t.length,k=0,i=0;. Кроме того, все эти слепки не нужны. - person BalusC; 14.08.2010
comment
+1 Мне нравится, как увеличивается количество символов ... Почему вы оставили символы новой строки / возврата, вы могли бы немного больше убрать все эти пробелы? - person ; 23.12.2010

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

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

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
person Community    schedule 14.08.2010

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)});
person Community    schedule 14.08.2010

КШ93 - 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
person Community    schedule 14.08.2010

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)))
person Community    schedule 13.08.2010

Java - 306 символов

Использование Java-решения BalusC в качестве основы:

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

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

person Community    schedule 20.08.2010

C - 163 161 символ

Добавлен флеш и удален ненужный поиск.

играл в гольф:

#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;
    }
}
person Community    schedule 08.12.2010
comment
вы можете сделать его короче, используя оператор и:? для if: `` while (fgets (& l, 2, f)) fseek (f, -1,1), putc (l ^ * k ++, f), fflush (f),! * k? k = p: 0; `` экономия 3 символа - person flownt; 11.01.2012

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

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

person Community    schedule 11.04.2012