Enigma a C#

Co je Enigma?
Enigma je elektromechanický šifrovací stroj, který byl široce používán německou armádou během druhé světové války. Na rozdíl od klasických ručních šifer, Enigma kombinovala rotory, reflektor a plugboard, aby vytvořila velmi složité šifrování. Výsledkem bylo, že každý znak textu byl transformován na jiný znak a tato transformace se neustále měnila s každým stiskem klávesy.
Princip fungování Enigmy
- Rotory – hlavní komponenta Enigmy. Každý rotor nahrazuje písmeno jiným písmenem a po každém stisknutí klávesy se rotor mírně otočí, čímž se mění substituce.
- Reflektor – rotor, který odráží signál zpět přes rotory, aby umožnil obousměrné šifrování, což znamená, že stejný stroj s tímto nastavením může šifrovat i dešifrovat.
- Plugboard (steckerbrett) – přepojovací panel, který umožňuje dodatečné párování písmen před vstupem do rotorů, čímž se zvyšuje složitost šifry.
- Denní nastavení – kombinace rotorů, jejich počátečních pozic a zapojení plugboardu tvořila tzv. denní klíč, který musel být předem znám jak u odesílatele, tak u příjemce.
Bezpečnost Enigmy
Enigma byla v době svého používání považována za velmi bezpečnou, protože počet možných konfigurací byl astronomický – kombinace rotorů, jejich pořadí, počáteční pozice a plugboardu poskytovala stovky trilionů možností. Přesto byla prolomena díky kombinaci:
- systematické práce kryptografů, zejména Alana Turinga a jeho týmu v Bletchley Parku,
- chybám v používání šifrovacích klíčů,
- využití známého textu a statistik při prolomení denních klíčů.
Příklad šifrování textu HELLO
V Enigmě nelze jednoduše demonstrovat kompletní proces ručně, protože výsledné písmeno závisí na aktuální pozici rotorů a plugboardu. Pro ilustraci lze uvést simulovaný výsledek při jednom konkrétním nastavení:
Text: HELLO
Zašifrovaný text: MFNCZ
Každé písmeno se mění podle složitého elektrického průchodu přes rotory a plugboard, a při každém stisku klávesy se konfigurace rotorů posune, takže další písmeno má úplně jinou substituci.
Implementace Enigma v C#
Zjednodušená
Implementace plné Enigmy je složitá, ale zjednodušenou verzi lze demonstrovat jedním rotorem a substituční tabulkou:
using System;
using System.Text;
internal class Program
{
private static readonly string Rotor = "EKMFLGDQVZNTOWYHXUSPAIBRCJ";
private static int _position;
private static void Reset(int startPosition = 0)
{
_position = (startPosition % 26 + 26) % 26;
}
private static string Encrypt(string input)
{
var sb = new StringBuilder(input.Length);
foreach (var ch in input.ToUpperInvariant())
sb.Append(EncryptChar(ch));
return sb.ToString();
}
private static string Decrypt(string input)
{
var sb = new StringBuilder(input.Length);
foreach (var ch in input.ToUpperInvariant())
sb.Append(DecryptChar(ch));
return sb.ToString();
}
private static char EncryptChar(char c)
{
if (c < 'A' || c > 'Z') return c;
var shiftedIndex = (c - 'A' + _position) % 26;
var mapped = Rotor[shiftedIndex];
Step();
return mapped;
}
private static char DecryptChar(char c)
{
if (c < 'A' || c > 'Z') return c;
var rotorIndex = Rotor.IndexOf(c);
if (rotorIndex < 0) return c;
var original = (rotorIndex - _position) % 26;
if (original < 0) original += 26;
var plain = (char)('A' + original);
Step();
return plain;
}
private static void Step()
{
_position = (_position + 1) % 26;
}
private static void Main()
{
var original = "HELLO";
Reset(0);
var encrypted = Encrypt(original);
Reset(0);
var decrypted = Decrypt(encrypted);
Console.WriteLine($"Original: {original}");
Console.WriteLine($"Encrypted: {encrypted}");
Console.WriteLine($"Decrypted: {decrypted}");
}
}
Plná
plná implementace Enigmy je o něco komplexnější, protože musí obsahovat:
- více rotorů, každý s vlastním posunem a zapojením,
- reflektor, který odráží signál zpět,
- plugboard (steckerbrett) pro párování písmen,
- rotaci rotorů (tzv. stepping), včetně „double-step“ mechanismu.
Níže je plná implementace Enigma v C#.
using System;
using System.Collections.Generic;
using System.Text;
internal class Program
{
private static readonly string[] _rotorWiring =
{
"EKMFLGDQVZNTOWYHXUSPAIBRCJ",
"AJDKSIRUXBLHWTMCQGZNPYFVOE",
"BDFHJLCPRTXVZNYEIWGAKMUSQO"
};
private static readonly char[] _notches = { 'Q', 'E', 'V' };
private static readonly int[] _positions = { 0, 0, 0 };
private static readonly string _reflector = "YRUHQSLDPXNGOKMIEBFZCWVJAT";
private static readonly Dictionary<char, char> _plugboard = new Dictionary<char, char>
{
{ 'A','B' }, { 'B','A' },
{ 'C','D' }, { 'D','C' }
};
private static void ResetPositions(char left, char middle, char right)
{
_positions[0] = left - 'A';
_positions[1] = middle - 'A';
_positions[2] = right - 'A';
}
private static string Encrypt(string text)
{
var filtered = FilterLetters(text);
var sb = new StringBuilder(filtered.Length);
foreach (var ch in filtered)
{
StepRotors();
var c = SwapPlugboard(ch);
for (var i = _rotorWiring.Length - 1; i >= 0; i--)
c = RotorForward(i, c);
c = _reflector[c - 'A'];
for (var i = 0; i < _rotorWiring.Length; i++)
c = RotorBackward(i, c);
c = SwapPlugboard(c);
sb.Append(c);
}
return sb.ToString();
}
private static string FilterLetters(string text)
{
var sb = new StringBuilder(text.Length);
foreach (var c in text.ToUpperInvariant())
{
if (c >= 'A' && c <= 'Z') sb.Append(c);
}
return sb.ToString();
}
private static char SwapPlugboard(char c) => _plugboard.TryGetValue(c, out var mapped) ? mapped : c;
private static void StepRotors()
{
if (AtNotch(1))
{
Step(0);
Step(1);
}
else if (AtNotch(2))
{
Step(1);
}
Step(2);
}
private static bool AtNotch(int rotorIndex) => (_positions[rotorIndex] + 'A') == _notches[rotorIndex];
private static void Step(int rotorIndex) => _positions[rotorIndex] = (_positions[rotorIndex] + 1) % 26;
private static char RotorForward(int rotorIndex, char c)
{
var pos = _positions[rotorIndex];
var wiring = _rotorWiring[rotorIndex];
var idx = (c - 'A' + pos) % 26;
return wiring[idx];
}
private static char RotorBackward(int rotorIndex, char c)
{
var pos = _positions[rotorIndex];
var wiring = _rotorWiring[rotorIndex];
var idx = wiring.IndexOf(c);
var result = (idx - pos + 26) % 26;
return (char)(result + 'A');
}
private static void Main(string[] args)
{
ResetPositions('A', 'A', 'A');
var original = "HELLO";
var encrypted = Encrypt(original);
ResetPositions('A', 'A', 'A');
var decrypted = Encrypt(encrypted);
Console.WriteLine($"Original: {original}");
Console.WriteLine($"Encrypted: {encrypted}");
Console.WriteLine($"Decrypted: {decrypted}");
}
}
Vysvětlení
- Rotory – tři rotory s nastavitelnou počáteční pozicí a „notch“ pro posun dalších rotorů.
- Reflektor – jednoduchý substituční řetězec, který odráží písmena zpět.
- Plugboard – umožňuje předem definované párování písmen.
- Kroky rotorů – implementuje mechaniku Enigmy včetně double-stepping efektu.
- Šifrování a dešifrování – stejná metoda, protože Enigma je symetrická.
Závěr
Enigma ukazuje, jak kombinace mechanických a elektrických prvků dokáže vytvořit extrémně složité šifrování. Přestože byla v době druhé světové války považována za téměř neprůstřelnou, její prolomení ukázalo, že i velmi složité šifry lze překonat kombinací matematiky, statistiky a znalostí systému. Enigma je dnes ikonou kryptografie a důležitým historickým příkladem evoluce šifrovacích metod.