Runenverschlüssler mit Rust

Das Programm “Runenverschlüssler” zeigt, wie man Text zwischen verschiedenen Zeichensätzen und Alphabeten verschlüsseln und entschlüsseln kann, wobei es das Base64-Alphabet und ein Fuþark mit jeweils 64 Zeichen verwendet.

Es wandelt das Base64-verschlüsselte Ergebnis in das Runenalphabet (Fuþark) um und gibt die runenverschlüsselte Version des Textes aus.

Das Programm wandelt das Runenalphabet wieder in das Base64-Alphabet zurück und gibt die entschlüsselte Base64-Version des Textes aus.

Schließlich entschlüsselt das Programm den Text von Base64 zurück in den Originaltext und gibt ihn aus.

Original:                    Gerald Allerstorfer
Encrypted (Base64):          R2VyYWxkIEFsbGVyc3RvcmZlcg==
Encrypted (Base64 to Runic): ᚱᛖᚵᛒᚸᚶᛑᛄᚨᚤᚥᛌᚻᚦᚵᛒᚼᛗᚱᛏᚼᛆᚹᛅᚼᛀ==
Decrypted (Runic to Base64): R2VyYWxkIEFsbGVyc3RvcmZlcg==
Decrypted:                   Gerald Allerstorfer

Cargo.toml

[package]
name = "rune-encrypter"
version = "0.1.0"
edition = "2021"

[dependencies]
base64 = "0.21.4"

main.rs

use base64::alphabet::Alphabet;
use base64::engine::{Engine, GeneralPurpose};

fn main() {
    // Text zuweisen und ausdrucken
    let original = "Gerald Allerstorfer";
    println!("Original:                    {}", original);

    // Alphabete definieren
    let alphabet_base64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    let alphabet_runic  = "ᚠᚡᚢᚣᚤᚥᚦᚧᚨᚩᚪᚫᚬᚭᚮᚯᚰᚱᚲᚳᚴᚵᚶᚷᚸᚹᚺᚻᚼᚽᚾᚿᛀᛁᛂᛃᛄᛅᛆᛇᛈᛉᛊᛋᛌᛍᛎᛏᛐᛑᛒᛓᛔᛕᛖᛗᛘᛙᛚᛛᛜᛝᛞᛟ";

    // Erstelle ein benutzerdefiniertes Alphabet für Base64 und eine Engine
    let alphabet = Alphabet::new(alphabet_base64).unwrap();
    let engine = GeneralPurpose::new(&alphabet, base64::engine::general_purpose::PAD);

    // Verschlüssle den Text in Base64 und drucke ihn aus
    let encrypted_base64 = engine.encode(original.as_bytes());
    println!("Encrypted (Base64):          {}", encrypted_base64);

    // Runenverschlüsselung
    // Wandle den Base64-Text in das Fuþark um und drucke ihn aus
    let encrypted_base64_runic: String = encrypted_base64
        .chars()
        .map(|c| {
            let index = alphabet_base64.chars().position(|x| x == c);
            match index {
                Some(i) => alphabet_runic.chars().nth(i).unwrap(),
                None => c,
            }
        })
        .collect();
    println!("Encrypted (Base64 to Runic): {}", encrypted_base64_runic);

    // Wandle die Base64-Runen zurück in das Base64-Alphabet und drucken
    let decrypted_base64: String = encrypted_base64_runic
        .chars()
        .map(|c| {
            let index = alphabet_runic.chars().position(|x| x == c);
            match index {
                Some(i) => alphabet_base64.chars().nth(i).unwrap(),
                None => c,
            }
        })
        .collect();
    println!("Decrypted (Runic to Base64): {}", decrypted_base64);

    // Wandle von Base64 zurück um und drucken
    let decrypted = engine.decode(&decrypted_base64).unwrap();
    let decrypted_str = String::from_utf8_lossy(&decrypted);
    println!("Decrypted:                   {}", decrypted_str);

    println!();
}

Runenverschlüsselung

In diesem Codeabschnitt wird der Base64-verschlüsselte Text in das Runenalphabet umgewandelt und dann ausgegeben. Lassen Sie uns die Schritte im Detail erklären:

let encrypted_base64_runic: String = encrypted_base64

Hier wird eine neue leere Zeichenfolge namens encrypted_base64_runic erstellt, die das Ergebnis der Umwandlung des Base64-Textes in das Runen-Alphabet speichern wird.

.chars()

Dies ist eine Methode, die auf einem Text (in diesem Fall encrypted_base64) aufgerufen wird und ihn in eine Sequenz von Zeichen aufteilt. Jedes Zeichen wird einzeln verarbeitet.

.map(|c| { ... })

Hier wird die map-Methode verwendet, um jedes Zeichen c im Base64-Text zu verarbeiten. Das bedeutet, dass der folgende Block von Code für jedes Zeichen im Text ausgeführt wird.

let index = alphabet_base64.chars().position(|x| x == c);

Dieser Code sucht nach dem Index (Position) des Zeichens c im Base64-Alphabet (alphabet_base64). Wenn das Zeichen gefunden wird, wird sein Index zurückgegeben, andernfalls wird None (keine Position) zurückgegeben.

match index { ... }

Dies ist eine Kontrollstruktur, die je nach dem Wert von index verschiedene Aktionen ausführt.

Some(i) => alphabet_runic.chars().nth(i).unwrap()

Wenn index einen Wert hat (es wurde ein Zeichen im Base64-Alphabet gefunden), wird die entsprechende Rune im Runen-Alphabet (alphabet_runic) anhand des Index i ausgewählt und in die Zeichenfolge encrypted_base64_runic hinzugefügt. Das .unwrap() wird verwendet, um sicherzustellen, dass der Index i gültig ist und keine Fehler verursacht.

None => c

Wenn index den Wert None hat (das Zeichen wurde nicht im Base64-Alphabet gefunden), wird das Zeichen c selbst in die Zeichenfolge encrypted_base64_runic hinzugefügt.

.collect()

Schließlich werden alle umgewandelten Zeichen zu einer Zeichenfolge zusammengefügt, und das Ergebnis wird in der Variable encrypted_base64_runic gespeichert.

Zusammengefasst: Dieser Code durchläuft den Base64-verschlüsselten Text Zeichen für Zeichen, sucht jedes Zeichen im Base64-Alphabet und ersetzt es durch das entsprechende Zeichen im Runen-Alphabet. Das Ergebnis ist eine Zeichenfolge, die den ursprünglichen Text im Runen-Alphabet darstellt.