题目详情

As on most challenge sites, there are some beginner cryptos, and often you get started with the good old caesar cipher.
I welcome you to the WeChall style of these training challenges :)

Enjoy!

XLI UYMGO FVSAR JSB NYQTW SZIV XLI PEDC HSK SJ GEIWEV ERH CSYV YRMUYI WSPYXMSR MW HKPRHJIEQTRW

题目要求

根据caesar cipher加密方法,解密给出的一串密文。

恺撒密码

在密码学中,恺撒密码(英语:Caesar cipher),或称恺撒加密、恺撒变换、变换加密,是一种最简单且最广为人知的加密技术。

它是一种替换加密的技术,明文中的所有字母都在字母表上向后(或向前)按照一个固定数目进行偏移后被替换成密文。

例如,当偏移量是3的时候,所有的字母A将被替换成D,B变成E,以此类推。这个加密方法是以罗马共和时期恺撒的名字命名的,当年恺撒曾用此方法与其将军们进行联系。

开始思考

有26个字母,除了给出的一段密文,还有25种转换,所以只需要对所有字符进行这些变换。

假设是原字符'A',从+1成为'B'开始,一直到+25成为'Z'

依次类推,假设原字符是'B',从+1成为'C'开始,一直到+24成为'Z',+25成为'A'

'B'+25后ascii值是'C'的后一个字符,所以需要判断是否超过了26个字母的范围,如果超过了,就要回头从'A'开始算。

核心处理

首先需要知道 字符'A' 的ascii码是65,'Z'的ascii码是90

所以核心代码就是 将原字符减去65然后对26取余,算出距离'A'的偏移,最后将偏移加上'A'就可以算出最终字符。

这样即使原字符'B'加25大于'Z',--------->>> 'B'+25=91
用它减去65然后对26取余就是0,---------->>> (91-65)%26=0
偏移量就是0, 0+'A'也就是'A'

所以算法已经确定好了。下面开始实现具体代码。

代码实现

Python

ord()函数就是用来返回单个字符的ascii值(0-255)或者unicode数值(),
相反地,chr()函数是输入一个整数【0,255】返回其对应的ascii符号。
.lower()函数将字符转成小写,便于观察。

cipher = 'JXU GKYSA RHEMD VEN ZKCFI ELUH JXU BQPO TEW EV SQUIQH QDT OEKH KDYGKU IEBKJYED YI TWBDTVUQCFDI'
#对整个字符串循环
for shift in range(25):
    #遍历字符串的每个字符
    for everyChar in cipher:
        if everyChar == ' ':
            print(' ',end='')
        else:
            integer = ord(everyChar)+shift+1
            print(chr((integer-65)%26 +65).lower(), end='')
    print()

运行结果:

ymj vznhp gwtbs ktc ozrux tajw ymj qfed itl tk hfjxfw fsi dtzw zsnvzj xtqzynts nx ilqsikjfrusx
znk waoiq hxuct lud pasvy ubkx znk rgfe jum ul igkygx gtj euax atowak yurazout oy jmrtjlkgsvty
aol xbpjr iyvdu mve qbtwz vcly aol shgf kvn vm jhlzhy huk fvby bupxbl zvsbapvu pz knsukmlhtwuz
bpm ycqks jzwev nwf rcuxa wdmz bpm tihg lwo wn kimaiz ivl gwcz cvqycm awtcbqwv qa lotvlnmiuxva
cqn zdrlt kaxfw oxg sdvyb xena cqn ujih mxp xo ljnbja jwm hxda dwrzdn bxudcrxw rb mpuwmonjvywb
dro aesmu lbygx pyh tewzc yfob dro vkji nyq yp mkockb kxn iyeb exsaeo cyvedsyx sc nqvxnpokwzxc
esp bftnv mczhy qzi ufxad zgpc esp wlkj ozr zq nlpdlc lyo jzfc fytbfp dzwfetzy td orwyoqplxayd
ftq cguow ndaiz raj vgybe ahqd ftq xmlk pas ar omqemd mzp kagd gzucgq eaxgfuaz ue psxzprqmybze
gur dhvpx oebja sbk whzcf bire gur ynml qbt bs pnrfne naq lbhe havdhr fbyhgvba vf qtyaqsrnzcaf
hvs eiwqy pfckb tcl xiadg cjsf hvs zonm rcu ct qosgof obr mcif ibweis gczihwcb wg ruzbrtsoadbg
iwt fjxrz qgdlc udm yjbeh dktg iwt apon sdv du rpthpg pcs ndjg jcxfjt hdajixdc xh svacsutpbech
jxu gkysa rhemd ven zkcfi eluh jxu bqpo tew ev squiqh qdt oekh kdygku iebkjyed yi twbdtvuqcfdi
kyv hlztb sifne wfo aldgj fmvi kyv crqp ufx fw trvjri reu pfli lezhlv jfclkzfe zj uxceuwvrdgej
lzw imauc tjgof xgp bmehk gnwj lzw dsrq vgy gx uswksj sfv qgmj mfaimw kgdmlagf ak vydfvxwsehfk
max jnbvd ukhpg yhq cnfil hoxk max etsr whz hy vtxltk tgw rhnk ngbjnx lhenmbhg bl wzegwyxtfigl
nby kocwe vliqh zir dogjm ipyl nby futs xia iz wuymul uhx siol ohckoy mifoncih cm xafhxzyugjhm
ocz lpdxf wmjri ajs ephkn jqzm ocz gvut yjb ja xvznvm viy tjpm pidlpz njgpodji dn ybgiyazvhkin
pda mqeyg xnksj bkt fqilo kran pda hwvu zkc kb ywaown wjz ukqn qjemqa okhqpekj eo zchjzbawiljo
qeb nrfzh yoltk clu grjmp lsbo qeb ixwv ald lc zxbpxo xka vlro rkfnrb plirqflk fp adikacbxjmkp
rfc osgai zpmul dmv hsknq mtcp rfc jyxw bme md aycqyp ylb wmsp slgosc qmjsrgml gq bejlbdcyknlq
sgd pthbj aqnvm enw itlor nudq sgd kzyx cnf ne bzdrzq zmc xntq tmhptd rnktshnm hr cfkmcedzlomr
the quick brown fox jumps over the lazy dog of caesar and your unique solution is dglndfeampns
uif rvjdl cspxo gpy kvnqt pwfs uif mbaz eph pg dbftbs boe zpvs vojrvf tpmvujpo jt ehmoegfbnqot
vjg swkem dtqyp hqz lworu qxgt vjg ncba fqi qh ecguct cpf aqwt wpkswg uqnwvkqp ku finpfhgcorpu
wkh txlfn eurzq ira mxpsv ryhu wkh odcb grj ri fdhvdu dqg brxu xqltxh vroxwlrq lv gjoqgihdpsqv

可以看到倒数第四行:

the quick brown fox jumps over the lazy dog of caesar and your unique solution is dglndfeampns

所以答案就是: dglndfeampns

注:每次刷新题目后所给的凯撒密码都不同 所以所得flag也将会不同

其他代码

C语言

#include <stdio.h>
#include <string.h>

int main(void)
{
    char caesar[] = "XLI UYMGO FVSAR JSB NYQTW SZIV XLI PEDC HSK SJ GEIWEV ERH CSYV YRMUYI WSPYXMSR MW HKPRHJIEQTRW";
    //对整个字符串循环
    for (int shift = 1; shift < 26; shift++)
    {
        //遍历字符串的每个字符
        for (int i = 0; i < strlen(caesar); i++)
        {
            if (caesar[i] == ' ')
            {
                printf("%c", caesar[i]);
            }
            else
            {
                //+32是为了转换为小写,便于观察
                printf("%c", ((caesar[i] + shift - 'A') % 26 + 'A')+32);
            }
        }
        printf("\n");
    }
    return 0;
}

Node.js

caesar = "XLI UYMGO FVSAR JSB NYQTW SZIV XLI PEDC HSK SJ GEIWEV ERH CSYV YRMUYI WSPYXMSR MW HKPRHJIEQTRW"
//对整个字符串循环
for (var shift = 1; shift < 26; shift++) {
    //遍历字符串的每个字符
    for (var Everychar in caesar) {
        if (caesar[Everychar] == ' ') {
            process.stdout.write(' ')
        } else {
            //+32是为了转换为小写,便于观察  
            process.stdout.write(String.fromCharCode((caesar[Everychar].charCodeAt() + shift - 65) % 26 + 65 + 32))
        }
    }
    console.log()
}

PHP

<?php
$caesar = "XLI UYMGO FVSAR JSB NYQTW SZIV XLI PEDC HSK SJ GEIWEV ERH CSYV YRMUYI WSPYXMSR MW HKPRHJIEQTRW"; 
//对整个字符串循环
for ($shift = 1; $shift < 26; $shift++) {
    //遍历字符串的每个字符
    for ($i = 0; $i < strlen($caesar); $i++) {
        if ($caesar[$i] == ' ') {
            echo(' ');
        }
        else {
            //+32是为了转换为小写,便于观察  
            echo(chr( (ord($caesar[$i])+$shift-ord('A')) %26 + ord('A') + 32));
        }
    }
    echo ("\n");
}
?>