Quest: Szyfry w JS

Szyfry podstawieniowe są łatwe do zrozumienia (i łatwe do złamania). Przetestuj te szyrowania i zrozum ich algorytmy. Zaszyfruj na kartce zdanie „To be or not to be” w ROT13, GADERYPOLUKI.

Szyfrowanie #1

Szyfr Cezara to szyfr podstawieniowy. Kod JS wykorzystuje numeryczne kody liter (ASCI). Dawniej napisano by go bez użycia kodów ASCI. Wygeneruj taki kod (np dla ROT13) i porównaj go z poniższym. Który jest łatwiejszy?

<!DOCTYPE html>
<html lang="pl">
<head>
  <meta charset="UTF-8" />
  <title>Szyfr Cezara</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    textarea { width: 100%; height: 80px; }
    select, input, button { margin: 10px 0; }
  </style>
</head>
<body>
  <h1>Szyfr Cezara</h1>

  <label>Tekst:</label><br>
  <textarea id="inputText"></textarea><br>

  <label>Przesunięcie (1-25):</label><br>
  <input type="number" id="shift" min="1" max="25" value="3"><br>

  <label>Tryb:</label><br>
  <select id="mode">
    <option value="encode">Zakoduj</option>
    <option value="decode">Odszyfruj</option>
  </select><br>

  <button id="runButton">Wykonaj</button>

  <h2>Wynik:</h2>
  <textarea id="outputText" readonly></textarea>

  <script>
    function caesar(str, shift, mode) {
      return str.split('').map(char => {
        const code = char.charCodeAt(0);

        const shiftAmount = mode === 'decode' ? -shift : shift;

        if (char >= 'A' && char <= 'Z') {
          return String.fromCharCode(((code - 65 + shiftAmount + 26) % 26) + 65);
        }
        else if (char >= 'a' && char <= 'z') {
          return String.fromCharCode(((code - 97 + shiftAmount + 26) % 26) + 97);
        }
        else {
          return char; // nie zmieniaj znaków specjalnych
        }
      }).join('');
    }

    document.getElementById('runButton').addEventListener('click', () => {
      const text = document.getElementById('inputText').value;
      const shift = parseInt(document.getElementById('shift').value);
      const mode = document.getElementById('mode').value;

      const result = caesar(text, shift, mode);
      document.getElementById('outputText').value = result;
    });
  </script>
</body>
</html>

Szyfrowanie #2

Szyfr GADERYPOLUKI to też szyfr podstawieniowy. Czym różni się Gaderypoluki od ROT13 w wersji nie wykorzystującej kodów ASCI?

<!DOCTYPE html>
<html lang="pl">
<head>
  <meta charset="UTF-8">
  <title>Szyfr GADERYPOLUKI</title>
  <style>
    body {font-family: Arial, sans-serif; background: #f5f5f5; padding: 20px; max-width: 600px; margin: auto;}
    textarea {width: 100%; height: 100px; margin-bottom: 10px; font-size: 16px; }
    button { padding: 10px 20px; margin-right: 10px; background-color: #007acc; color: white; border: none; border-radius: 5px; cursor: pointer; }
    .result { margin-top: 20px; padding: 15px; background: white; border: 1px solid #ccc; border-radius: 8px; }
  </style>
</head>
<body>

  <h2>Szyfr GADERYPOLUKI</h2>
  <p>Wpisz tekst do zaszyfrowania lub odszyfrowania (litery A-Z):</p>

  <textarea id="inputText" placeholder="Wpisz tutaj..."></textarea><br>
  <button onclick="encrypt()">Zaszyfruj / Odszyfruj</button>

  <div class="result">
    <strong>Wynik:</strong>
    <p id="output"></p>
  </div>

  <script>
    const keyPairs = {
      'G': 'A', 'A': 'G',
      'D': 'E', 'E': 'D',
      'R': 'Y', 'Y': 'R',
      'P': 'O', 'O': 'P',
      'L': 'U', 'U': 'L',
      'K': 'I', 'I': 'K'
    };

    function gaderypoluki(text) {
      return text.toUpperCase().split('').map(char => {
        return keyPairs[char] || char;
      }).join('');
    }

    function encrypt() {
      const input = document.getElementById('inputText').value;
      const output = gaderypoluki(input);
      document.getElementById('output').innerText = output;
    }
  </script>

</body>
</html>

Szyfrowanie #3

Szyfr BIFID jest połączeniem szyfru podstawieniowego z szyfrem przestawieniowym. Zaszyfruj na kartce zdanie „To be or not to be” w BIFID. Przetestuj poniższy kod i ulepsz dodając obsługę małych liter, polskich znaków i cyfr. Powiększ tablicę polybiusSquare do 9×9. Dlaczego takie szyfrowanie jest „mocniejsze”?

<!DOCTYPE html>
<html lang="pl">
<head>
  <meta charset="UTF-8">
  <title>Szyfrowanie Bifid - Demonstracja</title>
  <style>
    body {
      font-family: Arial, sans-serif;
      padding: 20px;
    }
    input, button {
      margin: 5px 0;
      padding: 8px;
    }
  </style>
</head>
<body>
  <h2>Szyfrowanie Bifid</h2>
  <label for="inputText">Wprowadź wiadomość (tylko litery):</label><br>
  <input type="text" id="inputText" placeholder="np. TAJNAWIADOMOSC"><br>
  <button onclick="encryptBifid()">Szyfruj</button>
  <button onclick="decryptBifid()">Deszyfruj</button>
  <h3>Wynik:</h3>
  <p id="output"></p>

  <script>
    const polybiusSquare = [
      ['A', 'B', 'C', 'D', 'E'],
      ['F', 'G', 'H', 'I', 'K'], // J = I
      ['L', 'M', 'N', 'O', 'P'],
      ['Q', 'R', 'S', 'T', 'U'],
      ['V', 'W', 'X', 'Y', 'Z']
    ];

    function getCoordinates(letter) {
      if (letter === 'J') letter = 'I';
      for (let row = 0; row < 5; row++) {
        for (let col = 0; col < 5; col++) {
          if (polybiusSquare[row][col] === letter) {
            return [row + 1, col + 1]; // +1 dla indeksu 1-based
          }
        }
      }
      return null;
    }

    function getLetter(row, col) {
      return polybiusSquare[row - 1][col - 1];
    }

    function encryptBifid() {
      let input = document.getElementById("inputText").value.toUpperCase().replace(/[^A-Z]/g, '');
      input = input.replace(/J/g, 'I');

      console.clear();
      console.log("--- Etapy szyfrowania Bifid ---");

      console.log("1. Oczyszczony tekst:", input);

      let rows = [];
      let cols = [];
      let coordinates = [];
      console.log("2. Współrzędne z tablicy Polybiusa:");
      for (let char of input) {
        const [r, c] = getCoordinates(char);
        rows.push(r);
        cols.push(c);
        console.log(`Litera ${char} → (${r}, ${c})`);
      }
      coordinates = rows.concat(cols);
      
      console.log("3. Lista wszystkich współrzędnych:", coordinates);


      let encrypted = '';
      console.log("4. Tworzenie nowych par i odczyt liter:");
      for (let i = 0; i < coordinates.length; i+=2) {
        const r = coordinates[i];
        const c = coordinates[i+1];
        const letter = getLetter(r, c);
        encrypted += letter;
        console.log(`(${r}, ${c}) → ${letter}`);
      }

      console.log("5. Zaszyfrowana wiadomość:", encrypted);
      document.getElementById("output").textContent = encrypted;
    }

    function decryptBifid() {
      let input = document.getElementById("inputText").value.toUpperCase().replace(/[^A-Z]/g, '');
      input = input.replace(/J/g, 'I');

      console.clear();
      console.log("--- Etapy deszyfrowania Bifid ---");

      console.log("1. Oczyszczony tekst:", input);

      let coordinates = [];
      console.log("2. Współrzędne z tablicy Polybiusa:");
      for (let char of input) {
        const [r, c] = getCoordinates(char);
        coordinates.push(r, c);
        console.log(`Litera ${char} → (${r}, ${c})`);
      }

      console.log("3. Lista wszystkich współrzędnych (r,c,r,c,...):", coordinates);

      const half = coordinates.length / 2;
      const rows = coordinates.slice(0, half);
      const cols = coordinates.slice(half);

      console.log("4. Podzielone współrzędne:");
      console.log("   Nowe wiersze:", rows);
      console.log("   Nowe kolumny:", cols);

      let decrypted = '';
      console.log("5. Tworzenie nowych par i odczyt liter:");
      for (let i = 0; i < rows.length; i++) {
        const r = rows[i];
        const c = cols[i];
        const letter = getLetter(r, c);
        decrypted += letter;
        console.log(`(${r}, ${c}) → ${letter}`);
      }

      console.log("6. Odszyfrowana wiadomość:", decrypted);
      document.getElementById("output").textContent = decrypted;
    }
  </script>
</body>
</html>

Twój komentarz

Zapisz moje dane, adres e-mail i witrynę w przeglądarce aby wypełnić dane podczas pisania kolejnych komentarzy.