Upload
others
View
0
Download
0
Embed Size (px)
Citation preview
6: 暗号解読に挑戦(II)
暗号化・復号プログラムの作成
2
ALPHABET = range(ord('a'), ord('z')) # 英字文字アルファベット
bun = input("Enter a string:") # 入力文字列から改行除法
cc = list(bun.encode("ascii")) # 文字列 → 文字コードの配列
for i, moji in enumerate(bun): # mojiはbunのi文字目を得る (iは0から始まる)
code = cc[i] # その文字のコードを得る
offset = code - ALPHABET[0] # 文字 a との差分
if code in ALPHABET: # 小文字アルファベットなら
print(moji, ": ", code, ", ", offset) # 差分まで表示する
else: # そうでない時は
print(moji, ": ", code) # 差分は表示しない
1. まずは,コピーしてきた復習用の code.py を実行してみよう
暗号化・復号プログラムの作成
3
ALPHABET = range(ord('a'), ord('z'))
# enc(秘密鍵 k, 平文 m) = 暗号文 c
def enc(k, m):
hira = list(m.encode("ascii")) # 文字列から文字コードの配列へ変換
ango = [0] * len(hira) # 暗号文(のコード)格納用配列
for i, code in enumerate(hira):
offset = code - ALPHABET[0] # 文字 a からの差分
ango[i] = # 暗号文用のコードの格納
c = bytes(ango).decode("ascii") # コードの配列を文字列に直す
return c
(参考)
使い方
2. これを参考に、caesar.py を完成させよう
k = 3
hirabun = input() # 平文を入力
angobun = enc(k, hirabun) # 暗号文に変換
# TODO: <-- ここを作る
暗号化・復号プログラムの作成
4
3. 作った caesar.py の使い方$ python caesar.py Hello, love you!Hhoor, oryh brx!
$ Hello, love you!
m.txt
前もって安全なところで作っておく
$ python caesar.py < m.txtHhoor, oryh brx!
$
??
Terminal 上での使い方
python caesar.py enc 3 < ファイル名
・ 入力データをファイルから読み込む
・ 出力をファイルに書き出す
python caesar.py dec 3 > ファイル名
※ 読み込んで書き出すことも可能
python caesar.py enc 3 < hirabun.txt > angobun.txt
暗号文(例)qxuvnb qjm knnw bnjcnm oxa bxvn qxdab rw brunwln frcq qrbuxwp, cqrw kjlt ldaenm xena j lqnvrlju enbbnu rw fqrlq qnfjb kanfrwp j yjacrldujauh vjuxmxaxdb yaxmdlc. qrb qnjmfjb bdwt dyxw qrb kanjbc, jwm qn uxxtnm oaxv vh yxrwc xo
解読プログラムのアイデア
5
qxuvnb qjm knnw bnjcnm oxa bxvn qxdab rw brunwln frcq qrbuxwp, cqrw kjlt ldaenm xena j lqnvrlju enbbnu rw fqrlq qnfjb kanfrwp j yjacrldujauh vjuxmxaxdb yaxmdlc. qrb qnjmfjb bdwt dyxw qrb kanjbc, jwm qn uxxtnm oaxv vh yxrwc xo
n が19回出現で最多
文字の出現頻度(英文)
(source: wikipedia)
一番多く現れる文字が e のはず!
英語の場合
解読:秘密鍵を知らない者が暗号文から平文を得ること
比較的長い英文を暗号化したものを解読したいどうすればよいか?レ
ポー
ト
解読プログラムのアイデア
6
qxuvnb qjm knnw bnjcnm oxa bxvn qxdab rw brunwln frcq qrbuxwp, cqrw kjlt ldaenm xena j lqnvrlju enbbnu rw fqrlq qnfjb kanfrwp j yjacrldujauh vjuxmxaxdb yaxmdlc. qrb qnjmfjb bdwt dyxw qrb kanjbc, jwm qn uxxtnm oaxv vh yxrwc xo
頻度配列
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
19
a b c d e f g h i j k l m n o p q r s t u v w x y z
差分
maxj0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
a b c d e f g h i j k l m n o p q r s t u v w x y z英語の場合
13 - 4 = 9 たけずれた ⇒ k = 9注意!maxj < 4 の時も大丈夫 ?!
1. 頻度配列 hindo を作る.2. 最大頻度の場所 maxj を見つける.3. k = maxj - 4 で求め,dec(k,angobun) で平文を求める.
アイデア
n が19回出現で最多
宿題3について
宿題
8
def enc(k, m):
msg = list(m.encode("ascii"))
c = ...return c
##### プログラム本文 #####k = 3hirabun = input("Hirabun:")angobun = enc(k, hirabun)print(angobun)
宿題 (1)
レポート
復号関数も同様にプログラム化しよう
a = list(m.encode("ascii"))
c = bytes(b).decode("ascii")
[0] [1] [2] [3] [4]
T o k y o 文字列(平文)m
84 111 107 121 111文字コートの配列a
84 114 110 98 114文字コートの配列b
T r n b r文字列(暗号文)c
各々+k だけずらす計算
宿題
9
ALPHABET = range(ord('a'), ord('z')) # 英字文字アルファベット
bun = input("Enter a string:") # 入力文字列から改行除法
cc = list(bun.encode("ascii")) # 文字列 → 文字コードの配列
for i, moji in enumerate(bun): # mojiはbunのi文字目を得る (iは0から始まる)
code = cc[i] # その文字のコードを得る
offset = code - ALPHABET[0] # 文字 a との差分
if code in ALPHABET: # 小文字アルファベットなら
print(moji, ": ", code, ", ", offset) # 差分まで表示する
else: # そうでない時は
print(moji, ": ", code) # 差分は表示しない
(参考)