VBAで暗号を実装しよう その3 ポリュビオス暗号
- はじめに
さてさて。
「暗号を実装しよう」の第3段です。
記事のストックがないので大急ぎで書いています笑
今回はポリュビオス暗号。
全く聞いたことない笑
- さっくと歴史
5*5の25マス目にアルファベットを入れて
各アルファベットを記入する代わりに
そのマス目の行列番号を記述していく
タイプのものです。
行列 | 1 | 2 | 3 | 4 | 5 |
---|---|---|---|---|---|
1 | a | b | c | d | e |
2 | f | g | h | I,j | k |
3 | l | m | n | o | p |
4 | q | r | s | t | u |
5 | v | w | x | y | z |
この表がフォーマルタイプ。
Go home を伝達したい場合は
書き手は
22 34 23 34 32 15
のように変換して
読み手は
表を見ながら
Gohome
と復元します。
これももっと詳しく知りたい方はググってきてください笑
- とりあえず暗号化
96 93 13 35 21 48 45 17 46 76 54 56 93 43 81 28 54 72 24 93 43 21 56 36 39 75 32 92 57 57 63 51 92 99 26 64 54 81 51 76 76 35 19 28 87 35 76 81 14 91 81 73 27 44 36 19 72 26 14 57 44 67 81
わー。
きーもーちーわーるーいー。
ほんとにぞわぞわする。
自分は暗号に触れる適性がないのかな笑
これがポリュビオス暗号です。
本来は全角の空行は入らないでしょうが
原文の見やすさのために取り入れました。
- 暗号について
またまた能書き。
この手のものは換字式暗号といいます。
「かんじ」じゃなくて「かえじ」って読むらしいです。
文字を何かに置き換えるってやつですね。
今回は文字を数字に置き換えています。
文字と数字が一対一対応になっているので
換字表を知っている人同士では簡単に読み書きできます。
じゃあ換字表を知らない人が解読するにはどうすればいいのか。
これって無理ゲーっぽいですよね。。
だって対応の起こりうるパターン数が多すぎるのだもの。
スキュタレー暗号のように物量作戦はむりですね。
じゃあ最強の暗号だ!!
と思いきや
これも現代ではすでにザルの暗号になっています。
頻度分析と呼ばれる手法によって。
これは
文字の出現頻度と暗号文での換字の出現頻度を対応付けて復元していくやり方です。
9世紀にすでに解読法が記録されているみたいですね。
でもポリュビオス暗号が生まれた時期が紀元前1世紀であることを考えると
記録上では800~900年くらいは解読不能(正確には難しい?)なツールだったのかもしれませんね。
- 暗号化のコード
今回はまず換字表を用意する必要があるので
それを作成するコードから
Function pattern_make() Dim trgt As Range Dim t As Integer Dim list() As Variant Dim d(0 To 1) As Integer Dim rp As Range Dim div As Integer '---------------------- '作業用シートで並び替えて 'listに書き込む '---------------------- Sheets.Add For i = 1 To 83 Cells(i, 1) = Chr(-32097 + (i - 1)) Cells(i, 2) = Rnd() Next t = Cells(1, 1).End(xlDown).Row Set trgt = Range(Cells(1, 1), Cells(t, 2)) trgt.Sort Cells(1, 2), xlAscending list = trgt Application.DisplayAlerts = False ActiveSheet.Delete Application.DisplayAlerts = True '---------------------------- '換字表を作成する '---------------------------- Set rp = Cells(11, 1) div = 9 For i = 1 To UBound(list, 1) d(0) = (i - 1) \ div + 1 d(1) = (i - 1) Mod div + 1 rp.Offset(d(0), d(1)) = list(i, 1) Next End Function
コードの中のdivという変数も結構だいじです。
だたこれは根性さえあれば暗号文から読み取れますが。
次にメインの関数
Sub polybius_coding() Dim str As String Dim str2 As String '------------------ 'strを読み込む '------------------ str = txt_input '------------------ 'strを暗号化 '------------------ str2 = coding(str) '------------------ 'str2を記述 '------------------ Call txt_output(str2) End Sub
形式は前回のスタキュレー暗号とほとんど一緒ですね。
というか一緒になるようにしています。
このコードの肝は関数codingなのですが
それはもちろんスタキュレーとは違う仕様です。
以下詳細。
Function coding(str) As String Dim pattern() As Integer Dim char As String Dim num As Integer Dim ans As String ReDim pattern(1 To 83) '------------------------ '換字表を読み込む '------------------------ pattern = pattern_input '------------------------ 'strを暗号化 '------------------------ For i = 1 To Len(str) char = Mid(str, i, 1) num = Asc(char) + 32098 If num < 1 Or 83 < num Then ans = ans & char Else ans = ans & pattern(num) & " " End If Next coding = ans End Function
この中にもさらに関数pattern_inputが入っています。
それで換字表を認識して
それに沿った変換をそれ以降で行っています。
その中でも特にいい感じのコードはこれ。
If num < 1 Or 83 < num Then ans = ans & char Else ans = ans & pattern(num) & " " End If
これによって換字表に入っていない文字はそのままの形で暗号文に組み込まれます。
全角のスペースとか
“―”これとか
“。”これとか
がそのまま読み込まれます。
やりたい人は
上の記号たちも換字表に入れちゃえばいいのかなと思います。
多分簡単にできると思いますよー。
- 復元のコード
換字表を持っていない状態での復元には頻度分析を使うと思いますが
頻度分析のプログラミングは難しそうなので
今回はスルーします。
今回は換字表を持っている人が復元する方法だけで。
ちなみに換字表は以下の通り。
行列 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
1 | ぇ | ぬ | か | ひ | し | げ | ゅ | ゐ | の |
2 | は | ど | ぺ | ほ | ゃ | も | つ | で | よ |
3 | そ | べ | ぞ | ぱ | い | る | び | ず | ふ |
4 | ぅ | む | ご | く | り | ぴ | へ | ぽ | ま |
5 | が | わ | ゆ | す | さ | あ | と | ゑ | ね |
6 | ぃ | や | ち | じ | せ | ゎ | ろ | め | ぼ |
7 | ぜ | に | を | づ | ぁ | お | み | え | ざ |
8 | う | ら | ぎ | ば | ぉ | だ | た | き | け |
9 | ょ | っ | ん | れ | ぶ | こ | ぐ | ぷ | て |
10 | ぢ | な |
まずはメイン
Sub polybius_restoration() Sheets("ポリュビオス").Activate Dim str As String Dim str2 As String '------------------ 'strを読み込む '------------------ str = txt_input '------------------ 'strを復元 '------------------ str2 = restoration(str) '------------------ 'str2を記述 '------------------ Call txt_output(str2) End Sub
次は関数coding
Function restoration(str) As String Dim pattern() As Integer Dim box As Variant Dim kaeji As Variant Dim d(0 To 1) As Integer Dim ans As String ReDim pattern(1 To 83) '------------------------ '換字表を読み込む '------------------------ pattern = pattern_input '------------------------ 'strを復元 '------------------------ box = Split(str, " ") kaeji = Range(Cells(12, 2), Cells(21, 10)) For i = LBound(box) To UBound(box) If Val(box(i)) = 0 Then ans = ans & box(i) Else d(0) = Mid(box(i), 1, Len(box(i)) - 1) d(1) = Right(box(i), 1) ans = ans & kaeji(d(0), d(1)) End If Next restoration = ans End Function
復元した結果はこちらー。
こんかいは ぽりゅぴおすあんごうです にほんごはあるふぁべっととちがって もじすうがおおいので たいおうひょうをつくるのにも ひとくろう
またしてもやる価値のない暗号化でした笑
あ。
そういえば換字表はシート上に出力しているので
そのセル番号がこのコードで考慮されていないものになってしまうと
正しく変換されなくなってしまいます。
これはちょっとシステムとして脆弱かも。。
どうやって解決しようかなー。
たぶんメモ帳に出力することになるんだろうけど。
今回はパスで。。
- まとめ
換字式の暗号は
換字表をどうやって共有するのかが肝ですね。
これを奪い取ることが一番楽な解読法な気がするもの笑
次回はまたちょっと「形式の修正」を行います。
関数の「txt_input」と「txt_output」に不満な部分があるので。。
具体的には
読み込み先、書き込み先のテキストファイルを選択できるようにします。
おわり。