pythonでシーザー(カエサル)暗号を復号する

2018/10/21

CTF python プログラミング

はじめに

最近バイクを買ってしまったせいで、競技プログラミングもあまりできていないにも関わらず、CTF(Capture The Flag)に興味を持ってしまいました...
(色々手を出してしまって、全部中途半端になってしまいそうです)

前置きはさておき、CTFの問題を扱っている「ksnctf」というサイトに登録しました。
最初の問題としてシーザー暗号が扱われており、pythonでシーザー暗号を復号するコードを書いたので紹介します。

シーザー暗号とは

シーザー暗号(シーザーあんごう、英語:Caesar cipher)は暗号理論上、もっともシンプルで、広く知られた暗号のひとつである[1]。カエサル式暗号[2]、シフト暗号[3]とも呼ばれる。
Wikipediaより引用

暗号の歴史は古代ローマ時代にまでさかのぼり,ジュリアス・シーザーがガリア=ローマ間の通信に用いたといわれる「シーザー暗号」が有名です。このシーザー暗号は,文字をアルファベット順に特定の文字数だけずらすといった非常に簡単なもので,換字式(かえじしき)暗号ともいいます。
IT用語辞典 より引用

上記の説明通り、文字列の一文字ずつを一定数ずらすだけで暗号化及び復号化が出来るシンプルな暗号です。

ASCIIコード表を用いて文字列のずらしを表現

ASCIIコードについての説明は以下を参考にしてください。

コンピュータは二進数しか扱えないため,文字データも二進数(つまり整数)として表現される.コンピュータは,ある二進数を特定の文字だと思いこんで処理する約束になっている.このような,文字を表現する二進数のことを特に文字コードと呼ぶ.
そこで,どの数値とどの文字を対応させるかを決めて,一覧表を作成することなる.現代のコンピュータでは標準的な文字コード表が決まっている.特にアルファベットと記号ではASCII(アスキー)コード表が使用される.
 ASCIIコード表より引用

今回使用するのは大文字のアルファベットと、小文字のアルファベットです。
大文字のアルファベットは65から90に割り当てられています。小文字のアルファベットは97から122に割り当てられています。

他の割り当てについて知りたい方はASCIIコード表を参考にしてください。

ksnctfの問題「Easy Cipher」

実際に問題を見てみます。

EBG KVVV vf n fvzcyr yrggre fhofgvghgvba pvcure gung ercynprf n yrggre jvgu gur yrggre KVVV yrggref nsgre vg va gur nycunorg. 

EBG KVVV vf na rknzcyr bs gur Pnrfne pvcure, qrirybcrq va napvrag Ebzr.

Synt vf SYNTFjmtkOWFNZdjkkNH. Vafreg na haqrefpber vzzrqvngryl nsgre SYNT.

何となくですが、英語の文章を変換したっぽく見えました(vf nとかがis aっぽい?)ので、一応それだと信じて復号化してみます。

pythonで復号化コードを実装


def caesar(data,num):
    ans = []
    for i in range(len(data)):
        temp = ord(data[i])
        if 97 <= temp <= 122: #ASCII CODE 97が"a", 122が"z"
            if temp - num < 97:#aの次はzとしている
                ans.append(chr(123-(97-(temp-num))))
            else:    
                ans.append(chr(temp-num))
        elif 65 <= temp <= 90:#ASCII CODE 65が"A",90が"Z"        
            if temp -num < 65:#Aの次はZとしている
                ans.append(chr(91-(65-(temp-num))))
            else:
                ans.append(chr(temp-num))
        else:
            ans.append(chr(temp))
    temp_ans = "".join(ans)
    if "is" in temp_ans or "am" in temp_ans or "are" in temp_ans :
        judge = True
    else:
        judge = False
    return temp_ans,judge
    # print("".join(ans))

if __name__ == "__main__":
    data = input("復号化する文字列\n")
    pos_ans =[] #答えとしての有力候補
    npos_ans =[]

    pos_index = []#何文字ずらしたか格納
    npos_index = []

    for i in range(1,26):
        temp_ans,judge = caesar(data, i)
        if judge:
            pos_ans.append(temp_ans)
            pos_index.append(i)
        else:
            npos_ans.append(temp_ans)
            npos_index.append(i)

    if len(pos_ans) != 0:
        print("\n有力候補")
        for i in range(len(pos_ans)):
            print("{}文字ずらした場合\n {}".format(pos_index[i],pos_ans[i]))
        print("\nその他")
        for i in range(len(npos_ans)):
            print("{}文字ずらした場合\n {}".format(npos_index[i],npos_ans[i]))
    else:
        print("有力候補は見つかりませんでした。")
        for i in range(len(npos_ans)):
            print("{}文字ずらした場合\n {}".format(npos_index[i],npos_ans[i]))

今回は元の暗号が英語っぽく見えたので、復号化した際に "is", "am","are"
が入っている場合に答えとして有力としています。

実行結果



有力候補
5文字ずらした場合
 ZWB FQQQ qa i aquxtm tmbbmz acjabqbcbqwv kqxpmz bpib zmxtikma i tmbbmz eqbp bpm tmbbmz FQQQ tmbbmza inbmz qb qv bpm itxpijmb. ZWB FQQQ qa iv mfiuxtm wn bpm Kimaiz kqxpmz, lmdmtwxml qv ivkqmvb Zwum. Ntio qa NTIOAehofJRAIUyeffIC. Qvamzb iv cvlmzakwzm quumlqibmtg inbmz NTIO.
9文字ずらした場合
 VSX BMMM mw e wmqtpi pixxiv wyfwxmxyxmsr gmtliv xlex vitpegiw e pixxiv amxl xli pixxiv BMMM pixxivw ejxiv mx mr xli eptlefix. VSX BMMM mw er ibeqtpi sj xli Geiwev gmtliv, hizipstih mr ergmirx Vsqi. Jpek mw JPEKWadkbFNWEQuabbEY. Mrwivx er yrhivwgsvi mqqihmexipc ejxiv JPEK.
13文字ずらした場合
 ROT XIII is a simple letter substitution cipher that replaces a letter with the letter XIII letters after it in the alphabet. ROT XIII is an example of the Caesar cipher, developed in ancient Rome. Flag is FLAGSwzgxBJSAMqwxxAU. Insert an underscore immediately after FLAG.
15文字ずらした場合
 PMR VGGG gq y qgknjc jcrrcp qszqrgrsrgml agnfcp rfyr pcnjyacq y jcrrcp ugrf rfc jcrrcp VGGG jcrrcpq ydrcp gr gl rfc yjnfyzcr. PMR VGGG gq yl cvyknjc md rfc Aycqyp agnfcp, bctcjmncb gl ylagclr Pmkc. Djye gq DJYEQuxevZHQYKouvvYS. Glqcpr yl slbcpqampc gkkcbgyrcjw ydrcp DJYE.
23文字ずらした場合
 HEJ NYYY yi q iycfbu bujjuh ikrijyjkjyed syfxuh jxqj hufbqsui q bujjuh myjx jxu bujjuh NYYY bujjuhi qvjuh yj yd jxu qbfxqruj. HEJ NYYY yi qd unqcfbu ev jxu Squiqh syfxuh, tulubefut yd qdsyudj Hecu. Vbqw yi VBQWImpwnRZIQCgmnnQK. Ydiuhj qd kdtuhisehu yccutyqjubo qvjuh VBQW.

その他
1文字ずらした場合
 DAF JUUU ue m euybxq xqffqd egnefufgfuaz oubtqd ftmf dqbxmoqe m xqffqd iuft ftq xqffqd JUUU xqffqde mrfqd uf uz ftq mxbtmnqf. DAF JUUU ue mz qjmybxq ar ftq Omqemd oubtqd, pqhqxabqp uz mzouqzf Dayq. Rxms ue RXMSEilsjNVEMYcijjMG. Uzeqdf mz gzpqdeoadq uyyqpumfqxk mrfqd RXMS.
2文字ずらした場合
 CZE ITTT td l dtxawp wpeepc dfmdetefetzy ntaspc esle cpawlnpd l wpeepc htes esp wpeepc ITTT wpeepcd lqepc te ty esp lwaslmpe. CZE ITTT td ly pilxawp zq esp Nlpdlc ntaspc, opgpwzapo ty lyntpye Czxp. Qwlr td QWLRDhkriMUDLXbhiiLF. Tydpce ly fyopcdnzcp txxpotlepwj lqepc QWLR.
3文字ずらした場合
 BYD HSSS sc k cswzvo voddob celcdsdedsyx mszrob drkd bozvkmoc k voddob gsdr dro voddob HSSS voddobc kpdob sd sx dro kvzrklod. BYD HSSS sc kx ohkwzvo yp dro Mkockb mszrob, nofovyzon sx kxmsoxd Bywo. Pvkq sc PVKQCgjqhLTCKWaghhKE. Sxcobd kx exnobcmybo swwonskdovi kpdob PVKQ.
4文字ずらした場合
 AXC GRRR rb j brvyun unccna bdkbcrcdcrxw lryqna cqjc anyujlnb j unccna frcq cqn unccna GRRR unccnab jocna rc rw cqn juyqjknc. AXC GRRR rb jw ngjvyun xo cqn Ljnbja lryqna, mnenuxynm rw jwlrnwc Axvn. Oujp rb OUJPBfipgKSBJVzfggJD. Rwbnac jw dwmnablxan rvvnmrjcnuh jocna OUJP.
6文字ずらした場合
 YVA EPPP pz h zptwsl slaaly zbizapabapvu jpwoly aoha ylwshjlz h slaaly dpao aol slaaly EPPP slaalyz hmaly pa pu aol hswohila. YVA EPPP pz hu lehtwsl vm aol Jhlzhy jpwoly, klclsvwlk pu hujplua Yvtl. Mshn pz MSHNZdgneIQZHTxdeeHB. Puzlya hu buklyzjvyl pttlkphalsf hmaly MSHN.
7文字ずらした場合
 XUZ DOOO oy g yosvrk rkzzkx yahyzozazout iovnkx zngz xkvrgiky g rkzzkx cozn znk rkzzkx DOOO rkzzkxy glzkx oz ot znk grvnghkz. XUZ DOOO oy gt kdgsvrk ul znk Igkygx iovnkx, jkbkruvkj ot gtioktz Xusk. Lrgm oy LRGMYcfmdHPYGSwcddGA. Otykxz gt atjkxyiuxk osskjogzkre glzkx LRGM.
8文字ずらした場合
 WTY CNNN nx f xnruqj qjyyjw xzgxynyzynts hnumjw ymfy wjuqfhjx f qjyyjw bnym ymj qjyyjw CNNN qjyyjwx fkyjw ny ns ymj fqumfgjy. WTY CNNN nx fs jcfruqj tk ymj Hfjxfw hnumjw, ijajqtuji ns fshnjsy Wtrj. Kqfl nx KQFLXbelcGOXFRvbccFZ. Nsxjwy fs zsijwxhtwj nrrjinfyjqd fkyjw KQFL.
10文字ずらした場合
 URW ALLL lv d vlpsoh ohwwhu vxevwlwxwlrq flskhu wkdw uhsodfhv d ohwwhu zlwk wkh ohwwhu ALLL ohwwhuv diwhu lw lq wkh doskdehw. URW ALLL lv dq hadpsoh ri wkh Fdhvdu flskhu, ghyhorshg lq dqflhqw Urph. Iodj lv IODJVzcjaEMVDPtzaaDX. Lqvhuw dq xqghuvfruh lpphgldwhob diwhu IODJ.
11文字ずらした場合
 TQV ZKKK ku c ukorng ngvvgt uwduvkvwvkqp ekrjgt vjcv tgrncegu c ngvvgt ykvj vjg ngvvgt ZKKK ngvvgtu chvgt kv kp vjg cnrjcdgv. TQV ZKKK ku cp gzcorng qh vjg Ecguct ekrjgt, fgxgnqrgf kp cpekgpv Tqog. Hnci ku HNCIUybizDLUCOsyzzCW. Kpugtv cp wpfgtueqtg koogfkcvgna chvgt HNCI.
12文字ずらした場合
 SPU YJJJ jt b tjnqmf mfuufs tvctujuvujpo djqifs uibu sfqmbdft b mfuufs xjui uif mfuufs YJJJ mfuufst bgufs ju jo uif bmqibcfu. SPU YJJJ jt bo fybnqmf pg uif Dbftbs djqifs, efwfmpqfe jo bodjfou Spnf. Gmbh jt GMBHTxahyCKTBNrxyyBV. Jotfsu bo voefstdpsf jnnfejbufmz bgufs GMBH.
14文字ずらした場合
 QNS WHHH hr z rhlokd kdssdq rtarshstshnm bhogdq sgzs qdokzbdr z kdssdq vhsg sgd kdssdq WHHH kdssdqr zesdq hs hm sgd zkogzads. QNS WHHH hr zm dwzlokd ne sgd Bzdrzq bhogdq, cdudknodc hm zmbhdms Qnld. Ekzf hr EKZFRvyfwAIRZLpvwwZT. Hmrdqs zm tmcdqrbnqd hlldchzsdkx zesdq EKZF.
16文字ずらした場合
 OLQ UFFF fp x pfjmib ibqqbo prypqfqrqflk zfmebo qexq obmixzbp x ibqqbo tfqe qeb ibqqbo UFFF ibqqbop xcqbo fq fk qeb ximexybq. OLQ UFFF fp xk buxjmib lc qeb Zxbpxo zfmebo, absbilmba fk xkzfbkq Oljb. Cixd fp CIXDPtwduYGPXJntuuXR. Fkpboq xk rkabopzlob fjjbafxqbiv xcqbo CIXD.
17文字ずらした場合
 NKP TEEE eo w oeilha happan oqxopepqpekj yeldan pdwp nalhwyao w happan sepd pda happan TEEE happano wbpan ep ej pda whldwxap. NKP TEEE eo wj atwilha kb pda Ywaown yeldan, zarahklaz ej wjyeajp Nkia. Bhwc eo BHWCOsvctXFOWImsttWQ. Ejoanp wj qjzanoykna eiiazewpahu wbpan BHWC.
18文字ずらした場合
 MJO SDDD dn v ndhkgz gzoozm npwnodopodji xdkczm ocvo mzkgvxzn v gzoozm rdoc ocz gzoozm SDDD gzoozmn vaozm do di ocz vgkcvwzo. MJO SDDD dn vi zsvhkgz ja ocz Xvznvm xdkczm, yzqzgjkzy di vixdzio Mjhz. Agvb dn AGVBNrubsWENVHlrssVP. Dinzmo vi piyzmnxjmz dhhzydvozgt vaozm AGVB.
19文字ずらした場合
 LIN RCCC cm u mcgjfy fynnyl movmncnoncih wcjbyl nbun lyjfuwym u fynnyl qcnb nby fynnyl RCCC fynnylm uznyl cn ch nby ufjbuvyn. LIN RCCC cm uh yrugjfy iz nby Wuymul wcjbyl, xypyfijyx ch uhwcyhn Ligy. Zfua cm ZFUAMqtarVDMUGkqrrUO. Chmyln uh ohxylmwily cggyxcunyfs uznyl ZFUA.
20文字ずらした場合
 KHM QBBB bl t lbfiex exmmxk lnulmbmnmbhg vbiaxk matm kxietvxl t exmmxk pbma max exmmxk QBBB exmmxkl tymxk bm bg max teiatuxm. KHM QBBB bl tg xqtfiex hy max Vtxltk vbiaxk, wxoxehixw bg tgvbxgm Khfx. Yetz bl YETZLpszqUCLTFjpqqTN. Bglxkm tg ngwxklvhkx bffxwbtmxer tymxk YETZ.
21文字ずらした場合
 JGL PAAA ak s kaehdw dwllwj kmtklalmlagf uahzwj lzsl jwhdsuwk s dwllwj oalz lzw dwllwj PAAA dwllwjk sxlwj al af lzw sdhzstwl. JGL PAAA ak sf wpsehdw gx lzw Uswksj uahzwj, vwnwdghwv af sfuawfl Jgew. Xdsy ak XDSYKorypTBKSEioppSM. Afkwjl sf mfvwjkugjw aeewvaslwdq sxlwj XDSY.
22文字ずらした場合
 IFK OZZZ zj r jzdgcv cvkkvi jlsjkzklkzfe tzgyvi kyrk ivgcrtvj r cvkkvi nzky kyv cvkkvi OZZZ cvkkvij rwkvi zk ze kyv rcgyrsvk. IFK OZZZ zj re vordgcv fw kyv Trvjri tzgyvi, uvmvcfgvu ze retzvek Ifdv. Wcrx zj WCRXJnqxoSAJRDhnooRL. Zejvik re leuvijtfiv zddvuzrkvcp rwkvi WCRX.
24文字ずらした場合
 GDI MXXX xh p hxbeat atiitg hjqhixijixdc rxewtg iwpi gteaprth p atiitg lxiw iwt atiitg MXXX atiitgh puitg xi xc iwt paewpqti. GDI MXXX xh pc tmpbeat du iwt Rpthpg rxewtg, stktadets xc pcrxtci Gdbt. Uapv xh UAPVHlovmQYHPBflmmPJ. Xchtgi pc jcstghrdgt xbbtsxpitan puitg UAPV.
25文字ずらした場合
 FCH LWWW wg o gwadzs zshhsf gipghwhihwcb qwdvsf hvoh fsdzoqsg o zshhsf kwhv hvs zshhsf LWWW zshhsfg othsf wh wb hvs ozdvopsh. FCH LWWW wg ob sloadzs ct hvs Qosgof qwdvsf, rsjszcdsr wb obqwsbh Fcas. Tzou wg TZOUGknulPXGOAekllOI. Wbgsfh ob ibrsfgqcfs waasrwohszm othsf TZOU.


出力結果を見ると13文字ずらした場合がきちんとした文章となっていることが分かります。

復号化した暗号を読むと、ROT13について説明しており、Flagは「FLAG_SwzgxBJSAMqwxxAU」ということが分かります。

追記

Python でシーザ暗号を実装するを読んだところ、26で割ったあまりを使う方法もあるみたいですね。こちらの方法がの方がシンプルに実装できそうです

自己紹介

はじめまして 社会人になってからバイクやプログラミングなどを始めました。 プログラミングや整備の記事を書いていますが、独学なので間違った情報が多いかもしれません。 間違っている情報や改善点がありましたらコメントしていただけると幸いです。

X(旧Twitter)

フォローお願いします!

ラベル

QooQ