Jak uruchomić kod
Najszybciej w przeglądarce: naciśnij F12, otwórz kartę Konsola, wklej kod i naciśnij Enter. Poza przeglądarką zapisz go jako caesar.js i użyj Node.js:
node caesar.jsJeśli sam szyfr jest dla ciebie nowy, zajrzyj do przewodnika, w którym nie ma kodu.
Jak działa ten kod
Pętla for...of czyta tekst znak po znaku, a wyrażenie regularne wybiera litery od A do Z, wielkie i małe. charCodeAt(0) podaje numer litery: 87 dla W, 119 dla w. Po odjęciu 65 lub 97 dostajesz miejsce w alfabecie, od 0 do 25.
Po dodaniu przesunięcia modulo zawija wynik, więc przy przesunięciu 3 litera Z trafia na C. String.fromCharCode robi z liczby z powrotem literę.
Cała reszta idzie gałęzią else i się nie zmienia. Dotyczy to także polskich liter, bo wyrażenie regularne ich nie obejmuje, dlatego „ś” w przykładzie zostaje na miejscu.
Deszyfrowanie w JavaScript
Druga funkcja nie jest potrzebna. Odszyfrowanie to takie samo przesunięcie w drugą stronę, więc wystarczy podać liczbę ujemną:
console.log(caesar("Zlwdm śzlhflh!", -3));// Witaj świecie!Stąd dodatkowe + 26 we wzorze. W JavaScript % zachowuje znak lewej liczby, więc -3 % 26 to -3 i String.fromCharCode zwróciłby zły znak. Po dodaniu 26 i ponownym modulo wychodzi 23, czyli A wraca na X. W wersji w Pythonie robi to sam operator %.
Szyfr Cezara na stronie WWW
To kompletna strona: zapisz ją jako plik .html i otwórz w przeglądarce. Wynik zmienia się w trakcie pisania, a wszystko dzieje się na twoim komputerze.
<textarea id="text"></textarea><input id="shift" type="number" value="3"><output id="result"></output> <script> // Tutaj wklej funkcję caesar const text = document.querySelector("#text"); const shift = document.querySelector("#shift"); const result = document.querySelector("#result"); function update() { result.textContent = caesar(text.value, Number(shift.value)); } text.addEventListener("input", update); shift.addEventListener("input", update);</script>Dwa szczegóły są tu ważne. Wartość pola to zawsze napis, więc przesunięcie przechodzi przez Number(). Wynik trafia na stronę przez textContent, bo innerHTML wykonałoby każdy HTML wpisany w pole.
Narzędzie wiersza poleceń w Node.js
Zastąp dwie ostatnie linijki caesar.js tym kodem, a przesunięcie i tekst będą pochodzić z wiersza poleceń:
const [shift, ...words] = process.argv.slice(2);console.log(caesar(words.join(" "), Number(shift))); // node caesar.js 3 Witaj// ZlwdmŁamanie szyfru metodą brute force
Przy 26 literach do sprawdzenia jest tylko 25 przesunięć, więc krótka pętla odczyta wiadomość bez klucza. Wystarczy znaleźć w wynikach linijkę, która ma sens:
function crack(text) { for (let shift = 1; shift < 26; shift++) { console.log(shift, caesar(text, -shift)); }} crack("Zlwdm śzlhflh!");// 1 Ykvcl śykgekg!// 2 Xjubk śxjfdjf!// 3 Witaj świecie!// ...Więcej o tej metodzie przeczytasz w artykule o ataku brute force, a łamacz online zrobi to samo w przeglądarce.
Krótsza wersja z replace
replace z globalnym wyrażeniem regularnym wywołuje twoją funkcję dla każdej litery, a resztę zostawia w spokoju. Pętla i else nie są już potrzebne.
const caesar = (text, shift) => text.replace(/[a-z]/gi, (char) => { const base = char <= "Z" ? 65 : 97; const code = char.charCodeAt(0) - base; return String.fromCharCode(((code + shift) % 26 + 26) % 26 + base); });Szyfr Cezara z polskimi znakami
Żeby przesuwać także ą, ć czy ż, zapisz alfabet w napisie i szukaj każdego znaku przez indexOf(). To ten sam alfabet, 35 znaków, którego używa nasze narzędzie:
const ALPHABET = "aąbcćdeęfghijklłmnńoópqrsśtuvwxyzźż"; function caesarAlphabet(text, shift) { const size = ALPHABET.length; let result = ""; for (const char of text) { const position = ALPHABET.indexOf(char.toLowerCase()); if (position === -1) { result += char; } else { const next = ALPHABET[((position + shift) % size + size) % size]; result += char === char.toLowerCase() ? next : next.toUpperCase(); } } return result;} console.log(caesarAlphabet("Zażółć gęślą jaźń", 3));// Acbrńę jhvnć łcąpZawijanie korzysta teraz z długości alfabetu, więc nie musisz nigdzie wpisywać 35. Wynik możesz porównać w narzędziu szyfru Cezara po wybraniu polskiego alfabetu.
Szyfrowanie pliku tekstowego
W Node.js odczyt i zapis pliku to po jednej linijce. Ten kod używa import, więc nazwij plik caesar.mjs albo ustaw "type": "module" w package.json.
import { readFileSync, writeFileSync } from "node:fs"; const text = readFileSync("message.txt", "utf8");writeFileSync("encrypted.txt", caesar(text, 3));Gotowa biblioteka
Jeśli potrzebujesz szyfru w projekcie i nie chcesz go utrzymywać, nasza biblioteka caesar-cipher-js nie ma zależności i zawiera typy TypeScript. Zainstaluj ją przez npm install caesar-cipher-js:
import { encrypt, decrypt } from "caesar-cipher-js"; console.log(encrypt("Witaj świecie!", 3));// Zlwdm śzlhflh!console.log(decrypt("Zlwdm śzlhflh!", 3));// Witaj świecie!Testowanie kodu
Node.js ma wbudowany moduł asercji, więc kilka linijek wyłapie większość błędów: przejście poza Z, zachowanie wielkości liter, pozostawienie interpunkcji i powrót do tekstu wyjściowego. Jeśli wszystko gra, program wypisze OK.
import assert from "node:assert/strict"; assert.equal(caesar("ABC", 3), "DEF");assert.equal(caesar("xyz", 3), "abc");assert.equal(caesar("Hello, World!", 5), "Mjqqt, Btwqi!");assert.equal(caesar(caesar("JavaScript", 7), -7), "JavaScript");assert.equal(caesar("A", -27), "Z");assert.equal(caesar("é", 3), "é");console.log("OK");Najczęstsze błędy
Najczęstszy to przesunięcie zostawione jako napis: 7 + "3" daje "73", a program po cichu zwraca złą literę. Drugi to % przy ujemnym przesunięciu, o czym była mowa wyżej. Nie używaj też innerHTML do pokazania wyniku, bo tekst pochodzi od użytkownika.
Najczęstsze pytania
Czy to działa w każdej przeglądarce?
Tak, wszystkie współczesne przeglądarki obsługują użytą tu składnię. Kod z tej strony uruchomiliśmy w Node.js 25, a stronę WWW sprawdziliśmy w przeglądarce.
Czy mogę tym chronić prawdziwe dane?
Nie. Pętla pokazana wyżej łamie ten szyfr w kilka sekund. Używaj go do nauki i łamigłówek. Do prawdziwych danych przeglądarki i Node.js udostępniają współczesne szyfrowanie przez Web Crypto API.
Jak sprawdzić, czy wynik jest poprawny?
Wpisz ten sam tekst i przesunięcie w narzędziu szyfru Cezara i porównaj. Ze swoich testów możesz też wywołać darmowe REST API.