凯撒转移


22

凯撒的转变可能是我们都熟悉的东西。

(您甚至可能将它作为一项家庭作业来完成。如果是这样,请不要复制这些答案,您的老师几乎可以肯定不想在这里得到任何类似答案的东西。)

以防万一,凯撒(Caesar)移位是一种非常简单的密码形式。它需要一个要加密的字符串和一个整数。然后,对字符串中的每个字母字符执行以下转换:

  1. 计算出字母在字母中的位置(从0开始)。
  2. 将开头收到的整数加到该数字上。
  3. 当数字大于25时,从中减去26。
  4. 计算出它所在的字母的位置。

其余字符保持不变。

必须尊重大写字母,因为没有大写字母的英语是什么?

例子:

abcdefghijklmnopqrstuvwxyz 1 -> bcdefghijklmnopqrstuvwxyza
Spam spam spam sausage and spam! 13 -> Fcnz fcnz fcnz fnhfntr naq fcnz!
abcdefghijklmnopqrstuvwxyz 52 -> abcdefghijklmnopqrstuvwxyz
abcdefghijklmnopqrstuvwxyz -1 -> zabcdefghijklmnopqrstuvwxy
ABCxyz 3 -> DEFabc

假设条件

  • 您可能会收到任何可打印的ASCII字符
  • 输入数字可以为负,并且始终大于-128且小于128(-128<x<128
  • 您必须能够对大写字母和非大写字母进行可逆编码。
  • 您必须创建完整的程序,而不仅仅是函数或代码段
  • 您将从STDIN或最接近的候补输入
  • 您可以选择输入格式,请在答案中注明
  • 需要转换的字符是ASCII码点0x41 - 0x5A0x61-0x7A-大写和小写字母

    • 大写字母应保持较高
    • 小写字母应保持较低
    • 不在此范围内的字符应保留原样
  • 请注意,对于此挑战,您只需要对字符串进行加密,就不必自动解决它们(但是给出-x密码会颠倒密码)


由于这是一个目录,因此可以竞争之后创建的语言。请注意,必须有一个解释器,以便可以测试提交。允许(甚至鼓励)自己为以前未实现的语言编写此解释器。除此之外,所有的标准规则必须遵守。大多数语言的提交都将以适当的预先存在的编码(通常为UTF-8)以字节计分。

目录

这篇文章底部的Stack Snippet会根据答案a)生成目录,a)作为每种语言最短解决方案的列表,b)作为整体排行榜。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

## Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以将旧分数保留在标题中,方法是将它们打掉。例如:

## Ruby, <s>104</s> <s>101</s> 96 bytes

如果要在标头中包含多个数字(例如,因为您的分数是两个文件的总和,或者您想单独列出解释器标志罚分),请确保实际分数是标头中的最后一个数字:

## Perl, 43 + 2 (-p flag) = 45 bytes

您还可以将语言名称设置为链接,然后该链接将显示在代码段中:

## [<><](https://esolangs.org/wiki/Fish), 121 bytes


8
“您甚至可能将它作为一项家庭作业来完成。如果是这样,请不要复制这些答案,您的老师几乎可以肯定不希望有任何类似答案的内容。” 我想知道如果您给老师一个90字节的混乱字符和快捷键,该
怎么办

Answers:


9

Pyth,13个字节

uXGH.<HQrBG1z

测试套件

基本上,我们从要进行凯撒转换的两个字符串开始,即小写字母和大写字母。包含这两个列表的列表是由rBG1,大写的分支生成的。然后,我们缩小该列表,从输入字符串开始,首先翻译小写字母,然后翻译大写字母,并进行适当的移位。


很好,我一直忘记分叉的存在...:P
FryAmTheEggman 2015年


5

Bash + bsd游戏包,21

caesar $[($1+130)%26]

内置FTW!几乎感觉像Mathematica。尽管Pyth的答案仍然较短。

从STDIN读取的输入字符串和从命令行的整数。例如:

$ ./caesar.sh 13 <<< "Spam spam spam sausage and spam!"
Fcnz fcnz fcnz fnhfntr naq fcnz!
$

或者,如果您不喜欢内置的:

Bash + coreutils,63岁

printf -va %s {a..z}
t=${a:$1%26}${a:0:$1%26}
tr A-Z$a ${t^^}$t

在我看来,coreutils版本不适用于-127和/或127?
尼尔

@尼尔是的。接得好。固定。
Digital Trauma 2015年

5

的JavaScript(ES6),122个 118 114 111字节

alert((p=prompt)().replace(/[a-z]/gi,c=>String.fromCharCode((x=c.charCodeAt(),a=x&96,x-a+n+129)%26-~a),n=+p()))

@Neil节省了4个字节!

说明

第一个提示将输入字符串。第二个是每个字母移动的数字。

alert(
  (p=prompt)()              // get input string
    .replace(/[a-z]/gi,c=>  // for each letter
      String.fromCharCode((
        x=c.charCodeAt(),   // x = code of character
        a=x&96,             // a = index of letter a (-1) in same capitalisation
        x-a+n+129)%26-~a    // add N to the letter code and wrap at 26
      ),                    // (+129 is needed to make the % work with negative numbers)
      n=+p()                // get number to shift by
    )
)

1
非常好!但这并不适用于所有输入。尝试一下"abcdefg", -26。可以通过将公式更改为来解决此问题(x-a+n+130)%26
ETHproductions 2015年

@ETHproductions感谢您捕捉到这一点!
user81655

“您必须创建完整的程序,而不仅仅是函数或代码段”
LegionMammal978 2015年

@ LegionMammal978谢谢,我没有注意到。
user81655

a=x&96,(x-a+n+129)%26+a+1帮助吗?
尼尔

3

CJam,34 22 21 20字节

感谢FryAmTheEggman保存1个字节。

l'[,_el^_26/l~fm<ser

在这里测试。

输入是在第一行上要移位的字符串,在第二行上要移位的字符串。

说明

l    e# Read the first line of input.
'[,  e# Push a string with all ASCII characters up to and including Z.
_el  e# Duplicate and convert to lower case. This only affects the letters.
^    e# Symmetric set-difference: except for the letters, each character appears in both
     e# sets and will be omitted from the difference, but all the letters will be included.
     e# This gives us "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".
_26/ e# Duplicate and split into chunks of 26 characters, separating lower and upper case.
l~   e# Read the second line of input and evaluate.
fm<  e# Shift each of the two substrings by that many characters to the left.
s    e# Convert to a single string, joining both substrings back together.
     e# On the stack are now the input, the letters in alphabetical order and the letters
     e# in shifted order.
er   e# Character transliteration: replace each occurrence of a letter with the character
     e# at the corresponding position in the shifted string.

@FryAmTheEggman这'[,_el^是丹尼斯的秘诀。我不知道您的意思f,但这似乎很正常吗?
马丁·恩德

我想我只是没有读足够的CJam答案:P像将其像地图一样使用但改变参数顺序似乎真的很整洁。
FryAmTheEggman 2015年

@FryAmTheEggman实际上,我根本不需要@。:)
Martin Ender 2015年

2

Java,249字节

这是我所能得到的。从标准输入读取会占用大量字节。使用命令行args的解决方案明显更短,但是此任务为输入指定了stdin。

输入格式为“字符串”,然后是换行号。

interface C{static void main(String[]a){java.util.Scanner r=new java.util.Scanner(System.in);String s=r.nextLine();int i=(r.nextInt()+26)%26;s.chars().forEach(c->System.out.print((char)(c>64&c<91|c>96&c<123?c<91?65+(c+i-65)%26:97+(c+i-97)%26:c)));}}

使用命令行参数,此解决方案仅为188字节。输入是字符串作为第一个参数,移位是第二个参数。

interface C{static void main(String[]a){int i=(Integer.parseInt(a[1])+26)%26;a[0].chars().forEach(c->System.out.print((char)(c>64&c<91|c>96&c<123?c<91?65+(c+i-65)%26:97+(c+i-97)%26:c)));}}

1

R,111字节

n=scan();s=scan(,"");for(l in as.numeric(sapply(s,charToRaw))){v=97;if(l<97)v=65;cat(intToUtf8((l+n-v)%%26+v))}

不打高尔夫球

n <- scan()                           # input integer
s <- scan(,"")                        # input string letter by letter
z <- as.numeric(sapply(s,charToRaw))  # get ASCII index of character
for (l in z){                         # loop through chars
  v=97                                # base index of not capitalized chars
  if(l<97)v=65                        # base index of capitalized chars
  cat(intToUtf8((l+n-v)%%26+v))       # paste the char of the shifted index
}

该程序从STDIN接收用户输入,首先是整数移位器,然后是逐字符的字符串。


1

Perl,81个字节

-p标志为+1 )

s/[^ ]+ //;$n=$&%26;eval"y/a-zA-Z/".($x=chr(97+$n)."-za-".chr$n+96).uc$x."/"if$n

仍在打高尔夫球...

测试:

llama@llama:...code/perl/ppcg67044caesar$ printf '1 abcdefghijklmnopqrstuvwxyz\n13 Spam spam spam sausage and spam!\n52 abcdefghijklmnopqrstuvwxyz\n-1 abcdefghijklmnopqrstuvwxyz\n3 ABCxyz' | perl -p caesar.pl; echo
bcdefghijklmnopqrstuvwxyza
Fcnz fcnz fcnz fnhfntr naq fcnz!
abcdefghijklmnopqrstuvwxyz
zabcdefghijklmnopqrstuvwxy
DEFabc


1

Python 2,163160字节

不知道我是否还能打高尔夫球。

import sys;k=sys.argv
def f(x,n):r=chr((ord(x.lower())-97+n)%26+97);return(x,[r,r.upper()][x.isupper()])
print''.join(f(x,int(k[2]))[x.isalpha()] for x in k[1])

由于它非常不可读,因此这里是一个非高尔夫版本:

import sys

def shift(x,n):
    # shift character x by n (all in lowercase)
    r = chr((ord(x.lower())-97+n)%26+97)
    if x.isalpha() and x.islower():
        return r
    elif x.isalpha() and x.isupper():
        return r.upper()
    else:
        return x

# 'map' the function shift to each character of the input   
output = ''.join(shift(x,int(sys.argv[2])) for x in sys.argv[1])
print(output)

关于输入:需要两个参数,第一个必须是字符串,第二个必须是整数(移位量)。示例(文件称为csr.py):

$ python csr.py gnu 9
pwd
$ python csr.py "Spam spam spam sausage and spam\!" 13
Fcnz fcnz fcnz fnhfntr naq fcnz!

注意:在第二个示例""中,需要转义字符和


1

Python 2,118 116字节

s,n=input()
print''.join([[c,chr((ord(c)-97+n)%26+97)]['`'<c<'{'],chr((ord(c)-65+n)%26+65)]['@'<c<'[']for c in s)

您可能要使用列表而不是if/else实例(codegolf.stackexchange.com/a/62/36885)。例如,print''.join([[c,chr((ord(c)-97+n)%26+97)]['~'<c<'{'],chr((ord(c)-65+n)%26+65)]['@'<c<'[']for c in s)略短一些,应该工作相同。(除非像以前一样将波浪号更改为反引号,否则我无法正确显示反引号。)
mathmandan 2015年

1

Mathematica,117个字节

Echo[InputString[]~StringReplace~Thread[Join[a=Alphabet[],b=ToUpperCase@a]->(c=RotateLeft)[a,d=Input[]]~Join~c[b,d]]]

接收字符串,后跟换行符,后跟移位因子。可能仍然可以打高尔夫球...


1

Perl 6,73 + 1 = 74字节

$ perl6 -pe 's:g:i/<[a..z]>/{chr ((my$o=ord ~$/)-(my$a=$o+&96+1)+BEGIN get%26)%26+$a}/' # 73+1

输入的第一行是向上移动字母的字符数。

用法:

$ perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \
'1
abcdefghijklmnopqrstuvwxyz'
bcdefghijklmnopqrstuvwxyza
$ perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \
'13
Spam spam spam sausage and spam!'
Fcnz fcnz fcnz fnhfntr naq fcnz!
$ perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \
'52
abcdefghijklmnopqrstuvwxyz'
abcdefghijklmnopqrstuvwxyz
$ perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \
'-1
abcdefghijklmnopqrstuvwxyz'
zabcdefghijklmnopqrstuvwxy
$ perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \
'3
ABCxyz'
DEFabc
$ perl6 -pe 's:g:i/<[a..z]>/{...}/' <<< \
'1000000000000000000000000000000000000000
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ'
mnopqrstuvwxyzabcdefghijkl
MNOPQRSTUVWXYZABCDEFGHIJKL

1

C ++,163个 154 152字节

#include<cstdio>
#include<cstdlib>
int main(int x,char**a){for(int c,b,s=atoi(a[1]);1+(c=getchar());putchar(c<b|c>b+26?c:(c+s-b+26)%26+b))b=c<97?65:97;}

用法:

$ ./caesar -1 <<< "123 a A z Z aBcDeFgHiKlMnOpQrStUvWxYz"
123 z Z y Y zAbCdEfGhJkLmNoPqRsTuVwXy

0

k4,80个字节

该程序接受班次号作为命令行参数,并从stdin读取文本。

由于技术上的限制,负移位必须用下划线而不是连字符减号编码。(如果不使用解析器来解释此编码,则解决方案将是64个字节。)

% wc -c c.k
80 c.k
% cat c.k
c:{x;,/x{y!(x_y),x#y}'.Q`a`A}
.z.pi:{1@x^c[.q.mod[.*{x^((!).$"_-")x}.z.x]26]x;}
% 

这是执行的示例:

% echo abcdefghijklmnopqrstuvwxyz|q c.k 1
bcdefghijklmnopqrstuvwxyza
% echo 'Spam spam spam sausage and spam!'|q c.k 13
Fcnz fcnz fcnz fnhfntr naq fcnz!
% echo abcdefghijklmnopqrstuvwxyz|q c.k 52
abcdefghijklmnopqrstuvwxyz
% echo abcdefghijklmnopqrstuvwxyz|q c.k _1
zabcdefghijklmnopqrstuvwxy
% echo ABCxyz|q c.k 3
DEFabc
%

这是一个愚蠢的小测试工具,可以同时验证编码和解码。(这是zsh; for bashksh,将for循环索引更改为((i=0;i<5;i++))。基于一个的数组,ugh ....)

% a=(abcdefghijklmnopqrstuvwxyz 'Spam spam spam sausage and spam!' abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz ABCxyz)
% b=(1 13 52 _1 3)
% c=(bcdefghijklmnopqrstuvwxyza 'Fcnz fcnz fcnz fnhfntr naq fcnz!' abcdefghijklmnopqrstuvwxyz zabcdefghijklmnopqrstuvwxy DEFabc)
% for ((i=1;i<=5;i++))
for> do
for>     r=$(echo "${a[i]}"|q c.k "${b[i]}")
for>     s=$(echo "$r"|if [[ ${b[i]} == _* ]]; then q c.k "${b[i]/_}"; else q c.k "_${b[i]}"; fi)
for>     printf '%s\t%s\n' "$([[ ${c[i]} == $r ]] && echo good || echo bad)" "$([[ ${a[i]} == $s ]] && echo good || echo bad)"
for> done
good    good
good    good
good    good
good    good
good    good
% 
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.