はじめに
CTF で手っ取り早くカエサル暗号を復号する Python プログラム作った話
Python には Rot13 (13文字ずらし) は実装されているが、それ以外では自作プログラムを走らせる必要がある
こんな感じのプログラムを作る
参考
Rot13 がよく使われるのは、アルファベットが26文字であることに由来する
復号も暗号化も、同じ変換でできるからだ
import codecs
s = codecs.decode("ここに文字", "rot13")
#1 基本
文字⇄ASCIIの変換には ord()
と chr()
関数を使う
###1-1 文字→ASCII
n = ord("ここに文字")
###1-2 ASCII→文字
s = chr(ここにASCIIコード)
参考
CTF で使いそうな文字
文字 | 文字コード |
---|---|
A | 65 |
B | 66 |
︙ | ︙ |
Z | 90 |
a | 97 |
︙ | ︙ |
z | 122 |
{ | 123 |
} | 125 |
#2 Python ソースコード
さっそく作っていく
今回のプログラムの仕様は以下
- コンソールで暗号を受け取る
- 一旦、ASCIIコードに変換し、1字ずらし〜25字ずらしを全て求める
- 特定のキーワードに一致するものを有力候補として表示
CaeserCipher.py
def caesar(data, num):
Ans = []
#ASCIIコードに変換
for i in range(len(data)):
Temp_ASCII = ord(data[i])
New_ASCII = Temp_ASCII - num #numだけずらす
if 97 <= Temp_ASCII <= 122: #a~z のASCIIコード
if New_ASCII < 97:
Ans.append(chr(123 - (97 - New_ASCII)))
else:
Ans.append(chr(New_ASCII))
elif 65 <= Temp_ASCII <= 90: #A~ZのASCIIコード
if New_ASCII < 65:
Ans.append(chr(91 - (65 - New_ASCII)))
else:
Ans.append(chr(New_ASCII))
else:
Ans.append(chr(Temp_ASCII))
Temp_Ans = "".join(Ans)
if "CTF" in Temp_Ans or "is" in Temp_Ans or "are" in Temp_Ans:
judge = True # {CTF, is, are}のいずれかを含む
else:
judge = False
return Temp_Ans, judge
if __name__ == "__main__":
data = input("Enter Your Cipher>> ")
Chosen_Ans = []
Defeated_Ans = []
Chosen_Shift_Count = []
Defeated_Shift_Count = []
for i in range(1, 26):
Temp_Ans, judge=caesar(data, i)
if judge:
Chosen_Ans.append(Temp_Ans)
Chosen_Shift_Count.append(i)
else:
Defeated_Ans.append(Temp_Ans)
Defeated_Shift_Count.append(i)
if len(Chosen_Ans) != 0:
print("\n有力")
for i in range(len(Chosen_Ans)):
print("{}文字ずらした:\t{}".format(Chosen_Shift_Count[i], Chosen_Ans[i]))
print("\nその他")
for i in range(len(Defeated_Ans)):
print("{}文字ずらした:\t{}".format(Defeated_Shift_Count[i], Defeated_Ans[i]))
else:
print("有力候補なし")
for i in range(len(Defeated_Ans)):
print("{}文字ずらした:\t{}".format(Defeated_Shift_Count[i], Defeated_Ans[i]))