UNPKG

crypto-keygen-suite

Version:

Key generation utilities for cryptographic operations. YES I RENAMED IT. SIX STATE PROTOCOL!!! See its folder for all <3

118 lines (104 loc) 3.22 kB
import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; function prepareKeyMatrix(key) { key = key.toUpperCase().replace(/J/g, "I").replace(/[^A-Z]/g, ""); const seen = new Set(); const matrix = []; for (const ch of key) { if (!seen.has(ch)) { matrix.push(ch); seen.add(ch); } } for (let i = 65; i <= 90; i++) { const ch = String.fromCharCode(i); if (ch === 'J') continue; if (!seen.has(ch)) { matrix.push(ch); seen.add(ch); } } const grid = []; for (let i = 0; i < 25; i += 5) { grid.push(matrix.slice(i, i + 5)); } return grid; } function findPosition(grid, letter) { for (let r = 0; r < 5; r++) { for (let c = 0; c < 5; c++) { if (grid[r][c] === letter) return [r, c]; } } return null; } function processText(text) { text = text.toUpperCase().replace(/J/g, 'I').replace(/[^A-Z]/g, ''); const result = []; for (let i = 0; i < text.length; i++) { let a = text[i]; let b = text[i + 1] || 'X'; if (a === b) { result.push(a); result.push('X'); } else { result.push(a); if (i + 1 < text.length) { result.push(b); i++; } else { result.push('X'); } } } return result; } function playfairCipher(text, grid, encrypt = true) { const shift = encrypt ? 1 : -1; const digrams = []; for (let i = 0; i < text.length; i += 2) { digrams.push([text[i], text[i + 1]]); } let output = ''; for (const [a, b] of digrams) { const [r1, c1] = findPosition(grid, a); const [r2, c2] = findPosition(grid, b); if (r1 === r2) { output += grid[r1][(c1 + shift + 5) % 5]; output += grid[r2][(c2 + shift + 5) % 5]; } else if (c1 === c2) { output += grid[(r1 + shift + 5) % 5][c1]; output += grid[(r2 + shift + 5) % 5][c2]; } else { output += grid[r1][c2]; output += grid[r2][c1]; } } return output; } const argv = yargs(hideBin(process.argv)) .usage('Usage: $0 <command> --key <key> --text <text>') .command('encrypt', 'Encrypt text', y => y .option('key', { type: 'string', demandOption: true, describe: 'Cipher key' }) .option('text', { type: 'string', demandOption: true, describe: 'Plaintext to encrypt' })) .command('decrypt', 'Decrypt text', y => y .option('key', { type: 'string', demandOption: true, describe: 'Cipher key' }) .option('text', { type: 'string', demandOption: true, describe: 'Ciphertext to decrypt' })) .demandCommand(1, 'You need to specify a command: encrypt or decrypt') .help() .argv; const command = argv._[0]; const key = argv.key; const text = argv.text; const matrix = prepareKeyMatrix(key); const processedText = processText(text); if (command === 'encrypt') { const encrypted = playfairCipher(processedText, matrix, true); console.log('Encrypted:', encrypted); } else if (command === 'decrypt') { const decrypted = playfairCipher(processedText, matrix, false); console.log('Decrypted:', decrypted); } else { console.error('Unknown command:', command); process.exit(1); }