凯撒(Caesar-Cypher)-Mania


22

凯撒Cypher支架是一个非常简单的置换密码其中每个字母是由固定的偏移(围绕Z的循环至A)移动。同样,我们也可以为一组可打印ASCII字符设置一个Caesar密码。这是从代码点0x20到0x7E的95个字符。对于给定的偏移量d,我们将代码点映射C

(C - 32 + d) % 95 + 32

会将所有字符移动a d并从~到循环。超出此范围的字符(控制字符,如换行符,制表符和ASCII范围以外的字符)不受影响。

您要编写两个程序或函数(可能使用不同的语言),它们需要一个偏移量d和一个字符串。第一个程序应返回或打印输入的凯撒密码。第二个程序应返回或打印凯撒密码(即使用offset -d)。您可以通过STDIN,命令行参数或函数参数进行输入。

为了使事情变得更有趣,第二个程序必须是第一个程序的凯撒密码。也就是说,如果将第一个程序的源代码传递给自身,则对于某些非零偏移量d,输出必须是第二个程序。

这两个程序以及输入字符串都必须仅包含可打印的ASCII字符,换行符和制表符。程序都不能包含任何注释,也不能直接或间接读取其自己的源代码,文件名或进程ID。

这是代码高尔夫球,因此最短的答案(以字节为单位)获胜。由于两个程序必须具有相同的大小,因此您只需要计算一次即可。

Answers:


12

Cjam,40 38 37字节

正向密码:

 q~'~),32>_@m<er "o|%|'*10<]>k<cpZ"_-

逆密码:

"s!)!+.54@aBo>gt"$q~'~),32>_@m>er\$a/

第二个程序是第一个的密码 2


怎么运行的

我在测试过程中想到了这个运气。

首先,Cypher部分:

q~'~),32>_@m<er
q~                 "Take the input and evaluate it";
  `~)              "Get the next character after the printable ASCII range";
     ,32>          "Get all printable ASCII characters":
         _@        "Copy the printable ASCII string and bring the cypher difference"
                   "on top of stack";
           m<      "Forward rotate the copy of printable ASCII string by difference";
                   "In case of inverse Cypher, this is m> to reverse rotate the string";
             er    "Transliterate to complete the forward/inverse Cypher";

现在来介绍棘手的部分。

关键的转变是

<space> -> "     // Empty space to string conversion
Z -> \           // Character Z in an useless string to swap operation
_ -> a           // Copy operation to wrapping in an array
- -> /           // Set subtraction to string splitting

所以第一个程序是

 q~'~),32>_@m<er "o|%|'*10<]>k<cpZ"_-
 q~'~),32>_@m<er                          "no-op space, Forward cypher, no-op space";
                 "o|%|'*10<]>k<cpZ"       "Useless String (Actually not)";
                                   _      "Copy it and ..."
                                    -     "remove all alphabets of copy from original";

第二个程序是

"s!)!+.54@aBo>gt"$q~'~),32>_@m>er\$a/
"s!)!+.54@aBo>gt"                       "Cypher of first part of first program"
                                        "with difference of 2";
                 $q~'~),32>_@m>er\$a/   "Cypher of the useless string of first program";
                                        "with difference 2";
                 $                      "Sort the first program's main part's cypher";
                  q~'~),32>_@m>er       "Program to reverse cypher";
                                 \$     "Swap the cypher to the top of stack and sort it";
                                   a    "Wrap it in array";
                                    /   "Split the output string on an array, which";
                                        "always returns the output in an array as there";
                                        "are no occurrences of an array in a string";

输入就像 "<escaped string to be cyphered>" <difference>

例如:

"abcd" 4

第一个程序的输出是

efgh

第二个程序是

]^_`

在这里在线尝试


那不是40个字节吗?也给在线解释器一个错误(Arraylists上的某些东西未实现)
Def 2014年

@Deformyer更正了字节数。您将输入作为什么?
Optimizer

是的,我不好,我以错误的顺序使用了参数。
Def 2014年

'“ q〜'〜),32> _ @ m <er” 9} o |%|'* 10 <]> k <cp}]“ _-” 2'不起作用(java.lang.RuntimeException:出乎意料的})
Def 2014年

1
@Deformyer您必须转义该字符串中的引号
Optimizer

7

Python 2,147

显然,我对此并不觉得太刻苦,因为它在Python中是徒劳的。仅存在两个单独的程序,未使用的程序用字符串括起来。

两个程序之间的偏移是39。

向前

定义接受Unicode字符串和偏移量的函数Z。

Z=lambda s,d:s.translate({i+32:(i+d)%95+32for i in range(95)})or u''and Z
"uE:F;=:XLd=rLfMK:GLE:M>`TBckjr`Be=a]qmckj?HKXBXBGXK:G@>`qmaVaHKXN__:G=X"

定义我接受Unicode字符串和偏移量的函数。

"d4)5*,)G;S,a;U<:)6;4)<-OC1RZYaO1R,PL`\RZY.7:G1G16G:)6/-O`\PEP7:G=NN)6,G"
I=lambda s,d:s.translate({i+32:(i-d)%95+32for i in range(95)})or u''and I

5

Python 3-248字节

我的目标是作为Python单一代码实现这一目标。进球成功,但现在我不能打高尔夫球了。

加密:

r=q="".__doc__[2];eval("p"+q+"int(''.join([c,ch"+q+"((o"+q+"d(c)-32+d)%95+32)][31<o"+q+"d(c)<127]fo"+q+" d in[int(input())]fo"+q+" c in input()))")or'\^UZ`smmyV[UZsGOwOT^ss[^PsOtx~}xPtp%!v~}tIG~|([^PsOt(|}$IR[^kPkUZGUZ`sUZ\a`sttIR[^kOkUZkUZ\a`sttt'

解密:

'Q&Q66Bssx$wssoFqOy+u!<6%6?&?6}#)<;;B~$}#<ow@w|6?&?6<<$6?&?6x<w=AGF?x=9MI?GF=qoGEP$6?&?6x<w=PEFKqz$6?&?64x4}#o}#)<}#%*)<==qz$6?&?64w4}#4}#%*)<===6=$';print("".join([c,chr((ord(c)-32-d)%95+32)][31<ord(c)<127]for d in[int(input())]for c in input()));

编辑:固定为不影响可打印ASCII范围之外的字符

从加密到解密的偏移量为20。首先输入偏移量,然后输入字符串,例如

5
hello

说明

以下转换是关键:

r -> '
' -> ;

第一个允许使用or,而第二个允许使用分号忽略字符串。

请注意,"".__doc__[2]返回字符串r(取自str)。这对于防止解密程序中的单引号字符串在中间带有引号是必要的。


5

Ruby,131125字节

这是我自己的呈文(我之前写过作为概念证明,但是我设法以某种方式违反了自己的规则)。我并没有在两个提交之间重用任何代码(毕竟,我希望你们都击败了它),而是由两行组成,其中一行变成了乱码。

正向密码:

Y=->d,s{s.chars{|c|x=c.ord;$><<(x<32?x:(x-32+d)%95+32).chr}};Y
"tdu<cKSKe;@9JKST;TPt;eGJ<r[uss_PsjivPq_Pdjid<`\plbji`e;@JUUr"

逆密码:

"eUf-T<D<V,1*;<DE,EAe,V8;-cLfddPAd[ZgAbPAU[ZS-QMa]S[ZQV,1;FFc"
J=->d,s{s.chars{|c|x=c.ord;$><<(x<32?x:(x-32-d)%95+32).chr}};J

这两个代码片段都定义了一个函数(Y在第一个和J第二个函数中称为),该函数接受一个整数和一个字符串,并将转换后的字符串打印到STDOUT。这两段代码之间的偏移量为40


4

oO CODE750 744字节,两个程序中都使用了所有代码

时间太长,但这可能是执行此操作的正确工具...

加密:

CcCcccccccccCcYcccCCCccCcCcCccccccCcCcccccCcCcccCcCccCccCcCCccccCcCccccCCcCccccCCccCccCcCCcccCCCcCccccCcCCcCCcCCcCcCcCccccCCccCccCccCccCccCccCccCccccccCCCcCccCccCCcCcCcccCCcCcccCcCCcCCcCcCCccCCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcccccccCccccCccccCCccccCCcCccCCcccCccccccccccCcCccCccCccCccCcCCccCCcccCcCcCccCCcccCCCcCcccccccccccccCCccCccCcCcCcccCCccccccccccCcCccccccCcCccccCCcCccCccCCcCccccccccccCCccCcCcCcccccCcCccCcCCCcCccCccCCcCccCccCccCcCcccccCcCcccCCCcCcCccccCcCccCCcCCcCCcCcCCcccCcCCcCCcCCcCCcCCcCCcCCcCCcCCcCcCcccCccCCcccccCcCcccCcccccCcccCcccCccCccCCcCcccccccccccccCCCcccCcCcCcccCcccCCCcCccCccCccCcCCccCccCcCCCcCccccCcCccccccccCcCccCccCcCCccccccCccccccccCcccCCccCccCccCCcCCcCCcCCcCcCcCcccccCcCCcCCcCCcCCcCCcCCcCCcCccCcCCcccCCccCcCcccCCcccCCCcCC

解密:

SsSsssssssssSsisssSSSssSsSsSssssssSsSsssssSsSsssSsSssSssSsSSssssSsSssssSSsSssssSSssSssSsSSsssSSSsSssssSsSSsSSsSSsSsSsSssssSSssSssSssSssSssSssSssSssssssSSSsSssSssSSsSsSsssSSsSsssSsSSsSSsSsSSssSSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsssssssSssssSssssSSssssSSsSssSSsssSssssssssssSsSssSssSssSssSsSSssSSsssSsSsSssSSsssSSSsSsssssssssssssSSssSssSsSsSsssSSssssssssssSsSssssssSsSssssSSsSssSssSSsSssssssssssSSssSsSsSsssssSsSssSsSSSsSssSssSSsSssSssSssSsSsssssSsSsssSSSsSsSssssSsSssSSsSSsSSsSsSSsssSsSSsSSsSSsSSsSSsSSsSSsSSsSSsSsSsssSssSSsssssSsSsssSsssssSsssSsssSssSssSSsSsssssssssssssSSSsssSsSsSsssSsssSSSsSssSssSssSsSSssSssSsSSSsSssssSsSssssssssSsSssSssSsSSssssssSssssssssSsssSSssSssSssSSsSSsSSsSSsSsSsSsssssSsSSsSSsSSsSSsSSsSSsSSsSssSsSSsssSSssSsSsssSSsssSSSsSS

Brainfuck翻译:

+>>>+>,<[->[->+>+<<]>[-<+>]<<]>,[>++++[-<-------->]+<<+[<+>+++]<++++++++++>>[>-<-<+<-[>>>+<<<<]<-[+<-]+>>>>]<<[-]>>>[->[-<+<<+>>>]<[->+<]+<<+<<<[>[-]+[>+<+++]>++++++++++[<<->+>->-[<<<+>>>>]-[+>-]+<<<]<<]+>[->>+<<]>>->>-]<<<++++[->++++++++<]>.[-]>,]
+>>>->,<[->[->+>+<<]>[-<+>]<<]>,[>++++[-<-------->]+<<+[<+>+++]<++++++++++>>[>-<-<+<-[>>>+<<<<]<-[+<-]+>>>>]<<[-]>>>[->[-<+<<+>>>]<[->+<]+<<+<<<[>[-]+[>+<+++]>++++++++++[<<->+>->-[<<<+>>>>]-[+>-]+<<<]<<]+>[->>+<<]>>->>-]<<<++++[->++++++++<]>.[-]>,]

oO CODE是Brainfuck的变体,仅字母的大小写很重要。

它使用第一个字节并将其字符代码用作d(因此换行符表示d = 10)。输入的其余部分是字符串。EOF为0。


4

GolfScript,95 64字节,两个程序中都使用了所有代码

加密:

0 0z{ 1)'[}??)9t:z21,--/; [84;%zt*84*84$|)21*|$Z!!\~'---|}`{)}%~

解密:

1!1{|!2*(\~@@*:u;{32-..0<!\95<&{u+95+95%}*32+}%[""] (...}~a|*~& 

输入格式:

1 "0 0z{ 1)'[}??)9t:z21,--/; [84;%zt*84*84$|)21*|$Z!!\~'---|}`{)}%~"

说明

解密:

1!1                            # Push 0 1.
{                              # Define a block and evaluate it.
    |                          # Or.
    !2*(                       # Get 1 for encryption, or -1 for decryption.
    \~                         # Evaluate the input string.
    @@*:u;                     # u = d for encryption, or -d for decryption.
    {                          # For each character:
        32-                    # Subtract 32.
        ..0<!\95<&             # Test if it is in the printable range.
        {u+95+95%}*            # If so, add u (mod 95).
        32+                    # Add 32 back.
    }%
    [""] (...                  # Push an empty array and 4 empty strings.
}~
a                              # No-op.
|*~                            # Evaluate ""*(""|"") which does nothing.
&                              # Calculate []&"" which is empty.

加密:

0 0                            # Push 0 0.
z                              # No-op.
{                              # Define a block and get its string representation.
    ...                        # See decryption code.
    |                          # This will be decoded into a }. The string will be truncated here when evaluated.
}`                             # Only the closing } will be truncated, but it is still used as the end of the block.
{)}%                           # Increment each character. Note that the braces before and after the block will also be incremented.
~                              # Evaluate the string.

3

使用Javascript(ES7草案) - 167个 165字节

借用@feersum对字符串的使用和@MartinButtner对分号的使用;)

加密:

J=(s,d)=>s.replace(/[ -~]/g,x=>String.fromCharCode((x.charCodeAt()-32+d)%95+32));J
"eP<T-Qef<V;.95*,.PW$HUG&W0TAef{=;270V/;86k1*;k8-.PPAV,1*;k8-.i=PQS^[U-QMa]S[ZQQc"

解密:

"t_Kc<`tuKeJ=HD9;=_f3WdV5f?cPtu+LJAF?e>JGEz@9JzG<=__Pe;@9JzG<=xL_`djib<`\plbji``r"
Y=(s,d)=>s.replace(/[ -~]/g,x=>String.fromCharCode((x.charCodeAt()+63-d)%95+32));Y

使用偏移: 55


1
空字符串失败。这就是为什么我不得不放or <empty string> and <function>而不是只放的原因or <function>
feersum 2014年

@feersum,它现在已修复...并且短了2个字节:)
nderscore 2014年

嗯,这看起来很熟悉。;)
Martin Ender 2014年

@MartinBüttner我不明白你的意思...;)
nderscore 2014年

2

> <>(鱼),467字节

加密:

ffii{{~~__:0a('0'*!.0a('0'*22(!'(~$~_:}-}$-a*}+{{if~~:i:0({}?;__:{}84{}*__({}?\__:{} _{}70{}g_{})_{}?\4__{}8*-_{}+{}80{}g_%4_{}8*{}+\\sl||||||||||||||||||||||||||||9||||||||||||||9||||||||||||||||||||||||||||||||||||||||||||||||||||9
                                                                              >                      >                              >!;7f7-_{}!%_{}!<872-d_{}!&_{}!<[755(7(%~~_{}!<[55(7(_{}!*!*23a(_{}!'_{}!"55(7((~~_{}~~~o__'4'0.{{{o,

解密:

iill~~""bb=3d+*3*-$13d+*3*-55+$*+"'"b=!0!'0d-!.~~li""=l=3+~!B>bb=~!;7~!-bb+~!B_bb=~!#b~!:3~!jb~!,b~!B_7bb~!;-0b~!.~!;3~!jb(7b~!;-~!.__vo                            <              <                                                    <
##############################################################################A######################A##############################A$>:i:0b~!$(b~!$?;:50gb~!$)b~!$?^:88+:+(""b~!$?^88+:+b~!$-$-56d+b~!$*b~!$%88+:++""b~!"""rbb*7*31~~~r/

这两个程序偏移3,它们采用以下形式的输入:

<2-digit offset> <text>

偏移量必须为2位数字,因此需要输入偏移量5 05

这是一个很长的提交,但是两个程序几乎都使用了非填充字符。肯定有很多空白可以使用,但是我认为这种方式会使程序更有趣。

此图像突出显示了两个程序使用的字符。

说明

使之成为可能的主要结构是_{} -> b~!,它允许在解密程序中任意跳过字符。怎么样?

Encrypt:
  _ : Mirror, but is a no-op if the program flow is horizontal
  { : Shift stack left
  } : Shift stack right

Decrypt:
  b : Push 11 to stack
  ~ : Pop top of stack
  ! : Skip the next instruction

总而言之,加密程序不执行任何操作,但是解密程序会跳过下一条指令。然后可以将其扩展为_{}! -> b~!$,从而允许在加密程序中任意跳过字符。

除此之外,程序的其余大部分都在推送数字,对这些数字执行操作,然后找到弹出它们的方法。例如,一个有用的构造是~~ -> "",该构造为加密程序弹出两个值,但在解密程序中不推送任何内容。


> <>,​​149个字节

这是不太有趣的版本,它使用以下事实:未传递的指令实际上是2D语言中的注释。

加密:

i68*:@-a*i@@-+i~v
4:v?)g31:;?(0:i:/8
(?v48*-+03g%48*+\*
_~\of0.   .1+1fo/
j*+:zq<6B99A6=qz6g
53Ji?C58/8;?r0?C5:
C?EiJ4r?<EFJ3;EtEg
:tAC5EK8l5tKK86t*i

解密:

^+-~/5"V~^55" ^sk
)/k4}\(&/04|%/^/$-
|4k)-~" %(\y)-~ Q~
TsQd[%#ttt#& &[d$
_~ /of1+7..6+2fo+\
*(?^48*-$-04g%48*/
84:^?)g41:;?(0:i:\
/i68*:@-a*i@@-+i~^

这两个程序偏移了84,并且以与上述相同的方式进行输入。第一条指令确定要执行程序的哪一半,i(输入)保持加密程序中的程序流向右,并在解密程序中^向上重定向程序流(从底部循环并从底部返回)。

说明

对于加密程序的相关部分(解密程序类似):

i                       read first input digit as char
68*:@-a*                subtract 48 (ASCII "0") and multiply by 10, keeping another 48 on the stack
i                       read second input digit as char
@@-+                    subtract 48 and add to 10*(first digit), giving the offset
i~                      read in space and discard it

--- LOOP ---
:                       copy the offset
i:                      read input char
:0)?;                   check if less than 0 (i.e. EOF) and terminate if so
:13g)?v                 check if greater than ~ in cell (1,3) and drop down if so
48*(?v                  check if less than 32 and drop down if so
48*-+03g%48*+           calculate Caesar shift of the char, fetching 95 from (0,3)

of1+1.                  repeat loop
of0.                    repeat loop

编码工具

这与上面的其余帖子无关,但是我认为我会发布它,因为我需要使用它:P

for(var i=0;i<95;++i){var option=document.createElement("option");option.text=i;document.getElementById("offset").add(option)};function update(m){if(m==1)var code=document.getElementById("in").value;else var code=document.getElementById("out").value;var offset=parseInt(document.getElementById("offset").value);var output="";for(var i=0;i<code.length;i++){var n=code[i].charCodeAt(0);if(n<32||n>127)output+=code[i];else{var c=(n-32+offset*m)%95;output+=String.fromCharCode(c<0?c+95+32:c+32)}}if(m==1)document.getElementById("out").value=output;else document.getElementById("in").value=output};
<html><body><textarea id="in" onkeyup="update(1)" rows=5 style="width:100%"></textarea><textarea id="out" rows=5 style="width:100%" onkeyup="update(-1)"></textarea><select id="offset" onchange="update(1)"></select></body></html>


1

Perl-131

它从命令行参数中获取输入。

We;{for(split//,$ARGV[1]){print chr(((ord$_)-32+$ARGV[0])%95+32)}};q!LUXmYVROZttqi'8-<AvCnaVXOTZeINXmmmUXJiEnrxwri'8-<AuCnj~zpxwnc!

将其移动26即可得到另一个:

q U6!*-B.+'$/IIF>[lapuKwC6+-$)/:}#-BBB*-~>yCGMLE>[lapuJwC?SOEMLC88U,;for(split//,$ARGV[1]){print chr(((ord$_)-32-$ARGV[0])%95+32)};

@MartinBüttnerWoah,赞好!它确实有效吗?
KSFT 2014年

据我所知;)
Martin Ender 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.