Inhalt
Die Fakten:
Plattform: | codewars.com |
Name: | ASCII Shift Encryption/Decryption |
Level: | 7 kyu |
Sprache: | TypeScript |
Beschreibung:
Ascii Shift Encryption/Decryption
The goal of this kata is to create a very simple ASCII encryption and decryption. The encryption algorithm should shift each character's charcode by the character's current index in the string (0-based).
The input strings will never require to go outside of the ASCII range.
Example:
p | a | s | s | w | o | r | d # Plaintext
+ 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 # Shift (add)
p | b | u | v | { | t | x | k # Ciphertext
The decryption should reverse this:
p | b | u | v | { | t | x | k # Ciphertext
- 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 # Shift (subtract)
p | a | s | s | w | o | r | d # Plaintext
Quelle: codewars.com
Lösung
Pseudo-Code
Wie immer gibt's reichlich Varianten, hier ist eine meiner.
Erst die Lösungsschritte in Pseudo-Code. Los geht’s:
Lösungsschritte
Schritt 1
Zuerst brauchen wir einen Loop.
Schritt 2
Dann addieren wir den aktuellen Index zu jedem Char-Code hinzu.
Schritt 3
Diesen neuen Char-Code wandeln wir dann wieder in ein Zeichen um.
Schritt 4
Ähnlich für die Entschlüsselungs-Funktion, nur dass wir hier den Index abziehen statt addieren.
Code
Geil. Übersetzen wir unseren Pseudo-Code in TypeScript:
Lösungsschritte
Meine erste Zeile der Verschlüsselungs-Funktion:
export function asciiEncrypt(plainText: string): string {
Jetzt der Loop:
return [...plaintext]
.map((char, i) => {
Ich versuch's hier mal mit Method-Chaining. Dazu wandele ich mir den String erst in ein Array um und loope dann mit .map()
.
Das return
können wir schon mal davor schreiben, weil wir sind ja gleich fertig 😉
Dann addieren wir den Index zum Char-Code des aktuellen Zeichens dazu und wandeln den neuen Char-Code wieder in ein Zeichen um:
const charCode = char.charCodeAt(0);
return String.fromCharCode(charCode + i);
})
Zum Schluss das Array wieder in einen String umwandeln:
.join("");
}
Jetzt die zweite Funktion. Der Verschlüsselungs-Funktion sehr, sehr ähnlich...
Hier die erste Zeile meiner Entschlüsselungs-Funktion:
export function asciiDecrypt(cipherText: string): string {
Loop-Loop:
return [...ciphertext]
.map((char, i) => {
Auch hier wieder direkt mit return
-Statement.
Hier müssen wir den Index vom Char-Code des aktuellen Zeichens abziehen bevor wir das Ergebnis in das neue Zeichen umwandeln:
const charCode = char.charCodeAt(0);
return String.fromCharCode(charCode - i);
})
Dann noch das Array wieder in einen String umwandeln:
.join("");
}
Voilá! 💪
Man hätte hier auch eine dritte Funktion schreiben können, die die ganze Logik enthält und als Parameter quasi nur das +
bzw. -
empfängt.
Hmm... eigentlich eine coole Bonus-Aufgabe... viel Spaß!
Komplettlösung
export function asciiEncrypt(plainText: string): string {
return [...plaintext]
.map((char, i) => {
const charCode = char.charCodeAt(0);
return String.fromCharCode(charCode + i); // Index addieren
})
.join("");
}
export function asciiDecrypt(cipherText: string): string {
return [...ciphertext]
.map((char, i) => {
const charCode = char.charCodeAt(0);
return String.fromCharCode(charCode - i); // Index abziehen
})
.join("");
}