Home » Tipps & Tricks » Algorithmen » Verschlüsselungen » Caesar-Chiffre

Caesar-Chiffre

Die Caesar-Chiffre ist eine einfache Verschlüsselung, die von Gaius Julius Caesar benutzt wurde und nach ihm benannt ist. Da es nur 25 möglichliche sinnvolle Schlüssel gibt, ist diese Verschlüsselung mit jedem Computer in Sekundenbruchteilen zu knacken und sollte deshalb nicht für sensible Daten verwendet werden.

Verschlüsselung

uses
  Math;

function EncryptCaesar(AText: string; AKey: Char): string;
var
  i: Integer;
  tmp: Integer;
  normedKey: Integer;
begin
  SetLength(Result, Length(AText));

  // alles in Großbuchstaben umwandeln
  // Caesar unterscheidet nicht zwischen Groß- und Kleinbuchstaben
  AText := UpperCase(AText);
  AKey := UpCase(AKey);

  if not (AKey in ['A'..'Z']) then
    raise EInvalidArgument.CreateFmt('Schlüssel ungültig(%s). AKey muss ein '
    + 'Buchstabe zwischen ''A'' und ''Z'' sein.', [AKey]);

  normedKey := Ord(AKey) - Ord('A') +1;   // Schlüssel normalisieren

  for i := 1 to Length(AText) do
  begin
    if AText[i] in ['A'..'Z'] then        // nur Buchstaben verschlüsseln
    begin
      tmp := (Ord(AText[i])) - Ord('A');  // Normalisieren
      tmp := (tmp + normedKey) mod 26;    // Verschieben
      Result[i] := Chr(tmp + Ord('A'));   // Denormalisieren
    end
    else
    begin
      Result[i] := AText[i];              // nicht verschlüsseln, wenn kein Buchstabe
    end;
  end;
end;

function DecryptCaesar(AText: string; AKey: Char): string;
var
  i: Integer;
  tmp: Integer;
  normedKey: Integer;
begin
  SetLength(Result, Length(AText));

  // alles in Großbuchstaben umwandeln
  // Caesar unterscheidet nicht zwischen Groß- und Kleinbuchstaben
  AText := UpperCase(AText);
  AKey := UpCase(AKey);

  if not (AKey in ['A'..'Z']) then
    raise EInvalidArgument.CreateFmt('Schlüssel ungültig(%s). AKey muss ein '
    + 'Buchstabe zwischen ''A'' und ''Z'' sein.', [AKey]);

  normedKey := Ord(AKey) - Ord('A') +1;   // Schlüssel normalisieren

  for i := 1 to Length(AText) do
  begin
    if AText[i] in ['A'..'Z'] then        // nur Buchstaben sind verschlüsselt
    begin
      tmp := (Ord(AText[i])) - Ord('A');  // Normalisieren
      tmp := (26 + (tmp - normedKey)) mod 26;    // Verschieben
      Result[i] := Chr(tmp + Ord('A'));   // Denormalisieren
    end
    else
    begin
      Result[i] := AText[i];              // nicht verschlüsseln, wenn kein Buchstabe
    end;
  end;
end;

Aufruf:

procedure TForm1.Button1Click(Sender: TObject);
begin
  Memo1.Text := EncryptCaesar(Memo1.Text, 'C');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
  Memo1.Text := DecryptCaesar(Memo1.Text, 'C');
end;

Mögliche Schlüssel sind Die Buchstaben 'A' bis 'Z', wobei bei Verwendung von 'Z' wieder der Klartext ausgegeben wird.
Ber der Caesar-Verschlüsselung wird das Alphabet um einen bestimmten Wert verschoben. Bei einer Verschiebung um 'C' bzw. 3, würde also 'A' zu 'D', 'B' zu 'E', 'C' zu 'F', usw. Weitere Informationen zur Caesar-Chiffre finden sich im Wikipedia-Artikel Verschiebechiffre.

Kryptoanalyse

Dass Caesar nicht besonders sicher ist, wurde ja schon gesagt. Wie aber lässt sich Caesar angreifen? Eine Möglichkeit wäre, einfach alle 25 mögliche Schlüssen durchprobieren. Allerdings muss man sich dann alle 25 Resultate ansehen um herauszufinden, was nun der richtige Schlüssel war. Demgegenüber gibt es eine ebenso einfache, aber praktikablere Lösung:

function GetCaesarKey(const AText: string): Char;
var
  letters: array['A'..'Z'] of Integer;
  i: Integer;
  mostFrequentChar: Char;
  c: Char;
begin
  FillChar(letters, SizeOf(letters), 0);

  // Häufigkeiten der einzelnen Buchstaben zählen
  for i := 1 to Length(AText) do
  begin
    if AText[i] in ['a'..'z', 'A'..'Z'] then
    begin
      Inc(letters[UpCase(AText[i])]);
    end;
  end;
  
  // häufigsten Buchstaben bestimmen
  mostFrequentChar := 'A';
  for c := 'B' to 'Z' do
  begin
    if letters[c] > letters[mostFrequentChar] then
      mostFrequentChar := c;
  end;
  
  // häufigsten Buchstaben als 'E' annehmen
  Result := Chr(((26 + Ord(mostFrequentChar) - Ord('A') - 5) mod 26) + Ord('A'));
end;

function CrackCaesar(const AText: string): string;
begin
  Result := DecryptCaesar(AText, GetCaesarKey(AText));
end;

Aufruf:

procedure TForm1.Button3Click(Sender: TObject);
begin
  Memo1.Text := CrackCaesar(Memo1.Text);
end;

In der deutschen Sprache ist der Buchstabe 'E' der häufigste. Buchstaben wie 'Q' sind hingegen sehr selten. So hat die deutsche Sprache eine charakteristische Buchstabenverteilung. Da bei der Caesar-Chiffre dem 'E' ein ganz bestimmter Buchstabe zugeordnet wird(und nicht etwa mehrere), können wir einfach den häufigsten Buchstaben ermitteln und schon wissen wir, welcher Buchstabe das 'E' sein muss. Die restlichen Buchstaben ergeben sich hier automatisch.

Das beschriebene Verfahren funktioniert allerdings nur, wenn der verschlüsselte Text eine ausreichende Länge besitzt. Wird beispielsweise nur das Wort „Delphiprogrammierer“ verschlüsselt, so ist hier der häufigste Buchstabe 'R' und nicht 'E'. Sind die Texte aber lang genug, funktioniert diese einfache Methode schon sehr gut.

Auch andere Verschlüsselungsverfahren lassen sich per Häufigkeitsanalyse knacken, wenn auch nicht ganz so einfach. Weitere Infos finden sich im Wikipedia-Artikel zur Häufigkeitsanalyse.