デバッグ地獄からの脱出 - エニグマ暗号機実装で学んだこと
2ヶ月ぶりのブログ更新です。今回は、C言語でエニグマ暗号機を実装した際に体験した「デバッグ地獄」とそこから学んだことを記録したいと思います。
きっかけ - なぜエニグマ暗号を作ろうと思ったか
最近、暗号について興味を持つようになりました。シーザー暗号やヴィジュネル暗号など、基本的な暗号アルゴリズムをC言語で実装してみて、その面白さに魅了されていました。
そんな中で出会ったのがエニグマ暗号機です。第二次世界大戦で実際に使われた暗号機として有名で、3つのローターとリフレクターを使った複雑な仕組みに興味を惹かれました。
「これをC言語で実装できたら面白そう!」
そう思って、次のプロジェクトとして挑戦することにしました。
実装過程 - ChatGPTとのやり取り、試行錯誤
正直なところ、私の現在の知識レベルでは、エニグマ暗号機の全コードを一から書くほどの技量はありません。
「今の知識で作ることができるのだろうか?」
そんな不安を抱えながら、ChatGPTにアイデアや実装について相談してみました。
- ローターのパターン定義
- 前進・逆変換の処理
- リフレクターの実装
- ローター回転の仕組み
ChatGPTとの対話を通じて、少しずつエニグマ暗号機の仕組みを理解し、実装のヒントを得ることができました。最初は複雑に見えた仕組みも、一つ一つの要素に分解してみると、意外と理解できるものでした。
最大の難関 - 復号化がうまくいかなかった問題
順調に進んでいた実装でしたが、大きな壁にぶつかりました。
暗号化はできるのに、復号化がうまくいかない
同じ設定で「HELLO」を暗号化してから復号化しても、「HELLO」に戻らないのです。
暗号化: HELLO → ILBDA
復号化: ILBDA → VZBKP // HELLOに戻らない!
この時に痛感したのは、生成AIを過信してはいけないということでした。ChatGPTが生成したコードも完璧ではありません。最終的には自分で実際に動かして、自分で問題を見つけて修正する必要があるのです。
デバッグの過程 - ローター回転タイミング、逆変換処理の修正
デバッグは試行錯誤の連続でした。
まず気づいたのはローター回転のタイミングの問題でした。元のコードでは:
- 文字を処理
- その後でローターを回転
という順序でしたが、実際のエニグマ暗号機は:
- まずローターを回転
- その後で文字を処理
という順序だったのです。
この修正だけでは問題が解決せず、さらに調べてみると逆変換処理にも問題がありました:
// 修正前
c = (rotor_inverse(rotor[i][0], c) - rotor_pos[i] + 26) % 26;
// 修正後
int adjusted_c = (c + rotor_pos[i]) % 26;
c = (rotor_inverse(rotor[i][0], adjusted_c) - rotor_pos[i] + 26) % 26;
動かして自分なりに推測して修正し、どうなったのかをChatGPTに伝えて修正案を得る、という流れを繰り返しました。問題を正確に伝えることが、効果的な解決策を得るために重要だと実感しました。
完成と感想 - 動いた時の達成感
そして遂に…
文字列を入力: ILBDA
復号化: HELLO
動いた!
この瞬間の達成感は、素晴らしいの一言でした。長時間のデバッグを経て、ついにエニグマ暗号機が正しく動作するようになったのです。
学んだこと - C言語、アルゴリズム、デバッグスキル
この経験を通じて学んだことは多岐にわたります:
技術的な学び
- C言語: ポインタや配列の扱い、関数設計の重要性
- アルゴリズム: 複雑な処理を段階的に分解する思考法
- デバッグスキル: 問題の切り分けと仮説検証のプロセス
より重要な学び
- トラブルについてうまく言語化することの大切さ: 問題を正確に説明できれば、解決策も見つかりやすい
- 自分に自信を持つこと: 完璧な知識がなくても、調べながら、試しながら、少しずつ前進することができる
おわりに
生成AIは非常に強力なツールですが、それに依存するのではなく、自分で考え、自分で検証し、自分で修正する姿勢が大切だと改めて感じました。
プログラミング学習において、「動かない→調べる→修正する→動いた!」のサイクルこそが、最も価値のある経験なのかもしれません。
次は何を作ってみようか、今からワクワクしています。
GitHub Repository: エニグマ暗号プログラム
開発環境: Visual Studio 2022, C言語
2025年9月 - 神酒まめ
