【Go】Goでエニグマを実装してみた

更新日:2025/3/13/(木) 12:38

タグ:Go

概要

暗号技術入門 第3版で最初の方に出てきた暗号、エニグマをGo実装してみた

サンプルコード

package main import ( "fmt" ) // ロータをシミュレートする var rotor = []string{ "EKMFLGDQVZNTOWYHXUSPAIBRCJ", // ロータ1 "AJDKSIRUXBLHWTMCQGZNPYFVOE", // ロータ2 "BDFHJLCPRTXVZNYEIWGAKMUSQO", // ロータ3 } // リフレクタをシミュレートする var reflector = "YRUHQSLDPXNGOKMIEBFZCWVJAT" // プラグボード設定 var plugboard = map[rune]rune{ 'A': 'B', 'B': 'A', 'C': 'D', 'D': 'C', 'E': 'F', 'F': 'E', // 他の設定を追加可能 } func rotate(rotor string, steps int) string { return rotor[steps:] + rotor[:steps] } func encryptChar(c rune, rotors []string, reflector string) rune { index := int(c - 'A') // 前進処理 for i := 0; i < len(rotors); i++ { index = int(rotors[i][index] - 'A') } // 反射 index = int(reflector[index] - 'A') // 後退処理 for i := len(rotors) - 1; i >= 0; i-- { for j := 0; j < 26; j++ { if int(rotors[i][j]-'A') == index { index = j break } } } return rune(index + 'A') } func plugboardSwap(c rune) rune { if swapped, exists := plugboard[c]; exists { return swapped } return c } func processMessage(message string) string { processed := make([]rune, len(message)) rotorPositions := []int{0, 0, 0} for i, char := range message { pluggedChar := plugboardSwap(char) // 現在の rotor 位置で文字をエンコード rotatedRotors := make([]string, len(rotor)) for j := range rotor { rotatedRotors[j] = rotate(rotor[j], rotorPositions[j]) } // 暗号化処理 encryptedChar := encryptChar(pluggedChar, rotatedRotors, reflector) // プラグボードの確認 processed[i] = plugboardSwap(encryptedChar) // ロータを回転 rotorPositions[0] = (rotorPositions[0] + 1) % 26 if rotorPositions[0] == 0 { rotorPositions[1] = (rotorPositions[1] + 1) % 26 if rotorPositions[1] == 0 { rotorPositions[2] = (rotorPositions[2] + 1) % 26 } } } return string(processed) } func main() { message := "HELLOENIGMA" encryptedMessage := processMessage(message) // ロータの位置をリセットして復号 decryptedMessage := processMessage(encryptedMessage) fmt.Println("元のメッセージ:", message) fmt.Println("暗号化メッセージ:", encryptedMessage) fmt.Println("復号化メッセージ:", decryptedMessage) } // 出力 // 元のメッセージ: HELLOENIGMA // 暗号化メッセージ: FIYHMJPFDKE // 復号化メッセージ: HELLOENIGMA