# 实施一次性垫

13

## 挑战

``````ENCRYPT
HAPPYBIRTHDAY
>ABKJAQLRJESMG
>HBZYYRTICLVME

DECRYPT
ABKJAQLRJESMG
HBZYYRTICLVME
>HAPPYBIRTHDAY
``````

`>`代表线路输出，所以你不必打印符号作为输出。

7

dmckee ---前主持人小猫，

1

dmckee ---前主持人小猫，2012年

7
@dmckee关于您的第一条评论，我同意，这就是为什么我不打算使用这些答案来确保我的通讯的安全。
PhiNotPi 2012年

1

ixtmixilix

@PhiNotPi我有个建议。如果他们使用真正的随机源（例如使用`/dev/hwrng`，而不是使用伪随机源（从技术上讲会使其破损），那么为什么不给予奖励）
PyRulez 2014年

8

## GolfScript，53个字符

``````n%(0=2%{~.,[{26rand 65+}*]:K]}*zip{{-}*~)26%65+}%K]n*
``````

GolfScript似乎非常适合此任务。

``````n %             # split input into an array of lines

# KEY GENERATION FOR ENCRYPTION MODE:
(               # extract the first line from the array
0 = 2 %         # check if the first char of that line is odd (E = 69)...
{               # ...and execute this block if it is:
~           # dump the remaining lines (of which the should be only one) on the stack
. ,         # calculate the length of the last line...
[ { 26 rand 65 + } * ]  # ...make an array of that many random letters...
:K          # ...and assign it to K
]           # collect all the lines, including K, back into an array
} *

# ENCRYPTION / DECRYPTION ROUTINE:
zip             # transpose the array of 2 n-char strings into n 2-char strings...
{               # ...and execute this block for each 2-char string:
{-} *       # subtract the second char code from the first
~ )         # negate the result (using the two's complement trick -x = ~x+1)
26 % 65 +   # reduce modulo 26 and add 65 = A
} %

# OUTPUT:
K ] n*         # join the result and K (if defined) with a newline, stringifying them
``````

4

# 红宝石（200 185）

``````\$ ruby onetimepad.rb
ENCODE
ANOTHERTESTINPUTZZZ
ZYCLGHDWLDASFUTHWKC
BPMIBXOXTPTQIVBMDPX
DECODE
ZYCLGHDWLDASFUTHWKC
BPMIBXOXTPTQIVBMDPX
ANOTHERTESTINPUTZZZ
``````
``````def f;gets.scan(/./).map{|b|b.ord-65};end
s=->a{a.map{|b|(b+65).chr}*''}
r=->b,a,o{s[a.zip(b).map{|a,b|(a.send o,b)%26}]}
puts(gets=~/^D/?r[f,f,:+]:[s[k=(p=f).map{rand 26}],r[k,p,:-]])``````

`s[k=(p=f).map{rand 26}],r[k,p,:-]`应该写成`s[k=f.map{rand 26}],r[k,\$_,:-]`
Hauleth 2012年

@Hauleth不行，因为`\$_`读的最后一行是行不通的`gets`。读完一行后`f`也可以`.scan(/./).map{|b|b.ord-65}`
jsvnm 2012年

3

``````import Random
main=newStdGen>>=interact.(unlines.).(.lines).f.randomRs('A','Z')
f k['E':_,x]=[z const k x,z(e(+))k x]
f _[_,k,x]=[z(e(-))k x]
e(%)k x=toEnum\$65+o x%o k`mod`26
``````

``````\$ runghc OneTimePad.hs <<< \$'ENCRYPT\nHELLOWORLD'
QMNQKGFZFD
XQYBYCTQQG
HELLOWORLD
``````

3

# Perl，220 171个字符

``````if(<>=~/D/){\$_=<>;\$w=<>;print chr((ord(substr\$w,\$i++,1)-ord\$1)%26+65)while/(.)/g}else{\$_=<>;\$c.=chr((ord(\$1)-65+(\$i=rand(26)))%26+65),print chr\$i+65while/(.)/g;print\$/.\$c}
``````

``````ENCRYPT
HELLO
CCTKK
JGEVY

DECRYPT
CCTKK
JGEVY
HELLO
``````

``````if(<>=~/D/){
\$_=<>;
\$w=<>;
print chr((ord(substr\$w,\$i++,1)-ord\$1)%26+65)while/(.)/g
}
else{
\$_=<>;
\$c.=chr((ord(\$1)-65+(\$i=rand(26)))%26+65),print chr\$i+65while/(.)/g;
print\$/.\$c
}
``````

Ilmari Karonen 2012年

2

# 蟒蛇- 304 295

``````import random
r=raw_input
R=lambda s:range(len(s))
o=lambda c:ord(c)-65
j=''.join
if r()[0]=='D':
s=r()
d=r()
print j(chr((o(s[i])-o(d[i]))%26+65)for i in R(s))
else:
s=r()
d=[random.randint(0,26)for i in R(s)]
print j(chr((o(s[i])+d[i])%26+65)for i in R(s))
print j(chr(n+65)for n in d)
``````

PhiNotPi 2012年

Gordon Bailey

1

## C ++ - 220 241个字符，4行

``````#include<cstdlib>
#include<cstdio>
#define a scanf("%s"
char i,s[99],t[99];int main(){a,t);a,s);if(t[0]>68){for(;s[i];++i)s[i]=(s[i]+(t[i]=rand()%26+65))%26+65;puts(t);}else for(a,t);s[i];++i){s[i]=65+t[i]-s[i];if(s[i]<65)s[i]+=26;}puts(s);}
``````

Ilmari Karonen

Scott Logan'3

1

## Python-270

``````import random
i=raw_input
m=i()
a=i()
r=range(len(a))
o=ord
j=''.join
if m=='ENCRYPT':
k=j(chr(65+random.randint(0,25)) for x in r)
R=k+"\n"+j(chr((o(a[x])+o(k[x]))%26+65) for x in r)
elif m=='DECRYPT':
k=i()
R=j(chr((o(k[x])-o(a[x]))%26+65) for x in r)
print R
``````

``````\$ python onetimepad.py
ENCRYPT
HELLOWORLD
UXCYNPXNNV
BBNJBLLEYY
DECRYPT
UXCYNPXNNV
BBNJBLLEYY
HELLOWORLD
``````

``````\$ wc -c onetimepad.py
``````

1

# J：94字节

``````3 :0]1
c=:(26&|@)(&.(65-~a.&i.))
r=:1!:1@1:
((],:+c)[:u:65+[:?26\$~#)@r`(r-c r)@.('D'={.)r 1
)
``````

``````3 :0]1                                          NB. Make a function and call it
c=:(26&|@)(&.(65-~a.&i.))                       NB. Adverb for operating on the alphabet
r=:1!:1@1:                                      NB. Read input line and decide (right to left)
((],:+c)[:u:65+[:?26\$~#)@r   ` (r-c r)            @. ('D'={.)r 1
NB. Encryption (ger    0)    | Decryption (ger 1)| Agenda
NB. pad,:(crypt=:plain + pad)| crypt - pad       | If D is first input, do (ger 1), else do (ger 0)
)
``````

1

# C＃（445416）

``````namespace G {
using System;
using System.Linq;
using x = System.Console;
class P {
static void Main() {
string p = "", c = "", k = "";
Random r = new Random();
int i = 0;
k=p.Aggregate(k,(l,_)=>l+(char)r.Next(65,90));
c=p.Aggregate(c,(m,l)=>m+(char)((l+k[i++])%26+65));
x.WriteLine(k + "\n" + c);
} else {
p=c.Aggregate(p,(l,a)=>l+(char)((a-k[i++]+26)%26+65));
x.WriteLine(p);
}
}
}
``````

}

``````namespace G{using System;using System.Linq;using x=System.Console;class P{static void Main(){string p="",c="",k="";Random r=new Random();int i=0;if (x.ReadLine()[0]=='E'){p=x.ReadLine();k=p.Aggregate(k,(l,_)=>l+(char)r.Next(65,90));c=p.Aggregate(c,(m,l)=>m+(char)((l+k[i++])%26+65));x.WriteLine(k+"\n"+c);}else{k=x.ReadLine();c=x.ReadLine();p=c.Aggregate(p,(l,a)=>l+(char)((a-k[i++]+26)%26+65));x.WriteLine(p);}}}}
``````

0

# C（159 + 11表示编译器标志）

``````d(a,b){return(a+b+26)%26+65;}a;char s[999],b,*c=s-1;main(){g;a=*s-69;g;while(*++c)a?b=-*c,*c=getchar():putchar(b=rand()%26+65),*c=d(*c,b);a||puts("");puts(s);}
``````

``````d(a,b){
//*a = (*a + b - 2*65 + 26) % 26 + 65;
return (a + b + 26) % 26 + 65;
}
a; char s[999], b, *c = s-1;
main(){
gets(s);
a = *s - 69; // -1 if decrypt 0 if encrypt
gets(s);
while(*++c){
if(!a)
putchar(b = rand() % 26 + 65); // 'A'
else
b = -*c, *c = getchar();
*c = d(*c,b);
}
if(!a) puts("");
puts(s);
}
``````

``````\$./onetimepad
ENCRYPT
FOOBAR
>PHQGHU
>UVEHHL
DECRYPT
PHQGHU
UVEHHL
>FOOBAR
``````

feersum

0

# JavaScript 239

``````var F=String.fromCharCode
function R(l){var k='';while(l--)k+=F(~~(Math.random()*26)+65);return k}
function X(s,k,d){var o='',i=0,a,b,c
while(i<s.length)a=s.charCodeAt(i)-65,b=k.charCodeAt(i++)-65,c=d?26+(a-b):a+b,o+=F((c%26)+65)
return o}
``````

``````var str = "HELLOWORLD";
var key = R(str.length);
var enc = X(str, key, false);
console.log(enc);
console.log(X(enc,key, true));
``````

0

# 红宝石- 184 179 177个字符

``````def g;gets.scan(/./).map{|c|c.ord-65}end
m,=g
k=(s=g).map{rand 26}
m==4?(puts k.map{|c|(c+65).chr}*'';y=:+):(k,s=s,g)
puts s.zip(k).map{|c,o|(c.send(y||:-,o).to_i%26+65).chr}*''
``````

``````def prompt
gets.scan(/./).map{ |c|c.ord - 65 }
end

mode = prompt[0]
operator = :-
secret = prompt
key = secret.map { |char| rand(26) }

if mode == 4 # the letter E, or ENCRYPT
key.map { |char| print (char + 65).chr }
puts
operator = :+
else
# make the old secret the new key,
# and get a new secret (that has been encrypted)
key, secret = secret, prompt
end

chars = secret.zip(key).map do |secret_char, key_char|

# if mode == 4 (E) then add, otherwise subtract
i = secret_char.send(operator, key_char).to_i

((i % 26) + 65).chr
end

puts chars.join("")
``````