Wie würde ich einen reversiblen Shuffle-Algorithmus in C # programmieren, der eine Taste zum Mischen verwendet und in den ursprünglichen Zustand zurückversetzt werden kann?
Zum Beispiel habe ich eine Zeichenfolge: "Hallo Welt", wie kann ich es mischen, so dass ich später in der Lage sein würde, die gemischte Zeichenfolge zurück zu "Hallo Welt" umzukehren.
Schauen Sie Fisher-Yates Shuffle nach, um die Zeichenfolge basierend auf einem Schlüssel zu permutieren . Füge den Schlüssel als Samen in einen PRNG ein, benutze diesen, um die Zufallszahlen zu erzeugen, die vom Mischen verwendet werden.
Nun, wie kann ich den Prozess umkehren? Fisher-Yates funktioniert durch den Austausch bestimmter Elementpaare. Um den Prozess umzukehren, können Sie denselben Schlüssel in dieselbe PRNG einspeisen und dann den Fisher-Yates-Algorithmus durchlaufen, als würden Sie ein Array mit der Größe Ihrer Zeichenfolge mischen. Aber eigentlich verschiebst du nichts, zeichne einfach die Indizes der Elemente auf, die in jeder Phase getauscht werden.
Sobald Sie dies getan haben, durchlaufen Sie Ihre Liste der Swaps umgekehrt und wenden Sie sie auf Ihre gemischte Zeichenfolge an. Das Ergebnis ist die ursprüngliche Zeichenfolge.
Nehmen wir zum Beispiel an, wir haben den String "hallo" mit den folgenden Swaps gemischt (ich habe hier keinen PRNG verwendet, ich habe Würfel geworfen, aber der Punkt über einen PRNG ist, dass Sie die gleiche Zahlenfolge erhalten mit dem gleichen Samen):
%Vor%Also ist die gemischte Zeichenfolge "loelh".
Um zu entmischen, erzeuge ich die gleiche Reihe von "zufälligen" Zahlen, 0, 3, 1, 0. Wenden Sie dann die Swaps in umgekehrter Reihenfolge an:
%Vor%Erfolg!
Der Nachteil davon ist natürlich, dass es eine Menge Speicher für die Entschleierung benötigt: ein Array von Indizes, so lang wie Ihr ursprüngliches Array von Zeichen. Bei wirklich riesigen Arrays sollten Sie also eine PRNG (oder eine Sequenzerstellungsfunktion) wählen, die entweder vorwärts oder rückwärts bewegt werden kann, ohne die gesamte Ausgabe speichern zu müssen. Dies schließt Hash-basierte kryptographisch sichere PRNGs aus, aber LFSRs sind reversibel.
Übrigens, warum willst du das machen?
Hier ist eine einfache Implementierung von dem, was Sie brauchen (wenn ich es gut verstanden habe):
%Vor%Verwendung:
%Vor%Der Schlüssel muss eine Ganzzahl sein. Wenn Sie eine Zeichenfolge als Passwort verwenden müssen, rufen Sie einfach GetHashCode () auf:
%Vor%BEARBEITEN:
Jetzt ist genau eine Fisher-Yates Shuffle-Algorithmus-Implementierung. Danke an Jeff für den Code
Sie können sich die folgende Frage ansehen und es sind Antworten. Verschlüsseln / entschlüsseln Zeichenfolge in .NET
Eine Java-Frage wird auch hier umgeleitet, also hier ist die vollständige kryptografische Java-Implementierung:
%Vor%