Data update
This commit is contained in:
parent
72eb4943cb
commit
4d5544505c
2347 changed files with 62432 additions and 16731 deletions
|
|
@ -1,4 +1,4 @@
|
|||
proc prepare . s$ .
|
||||
proc prepare &s$ .
|
||||
for e$ in strchars s$
|
||||
h = strcode e$
|
||||
if h >= 97
|
||||
|
|
|
|||
199
Task/Bifid-cipher/JavaScript/bifid-cipher.js
Normal file
199
Task/Bifid-cipher/JavaScript/bifid-cipher.js
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
// ADFGVX Cipher Implementation in JavaScript
|
||||
|
||||
// Cipher squares
|
||||
const squareRosetta = [ // from Rosetta Code
|
||||
['A', 'B', 'C', 'D', 'E'],
|
||||
['F', 'G', 'H', 'I', 'K'],
|
||||
['L', 'M', 'N', 'O', 'P'],
|
||||
['Q', 'R', 'S', 'T', 'U'],
|
||||
['V', 'W', 'X', 'Y', 'Z'],
|
||||
['J', '1', '2', '3', '4']
|
||||
];
|
||||
|
||||
const squareWikipedia = [ // from Wikipedia
|
||||
['B', 'G', 'W', 'K', 'Z'],
|
||||
['Q', 'P', 'N', 'D', 'S'],
|
||||
['I', 'O', 'A', 'X', 'E'],
|
||||
['F', 'C', 'L', 'U', 'M'],
|
||||
['T', 'H', 'Y', 'V', 'R'],
|
||||
['J', '1', '2', '3', '4']
|
||||
];
|
||||
|
||||
// Test text strings
|
||||
const textRosetta = "0ATTACKATDAWN";
|
||||
const textRosettaEncoded = "DQBDAXDQPDQH"; // only for test
|
||||
const textWikipedia = "FLEEATONCE";
|
||||
const textWikipediaEncoded = "UAEOLWRINS"; // only for test
|
||||
const textTest = "The invasion will start on the first of January";
|
||||
const textTestEncoded = "RASOAQXFIOORXESXADETSWLTNIAZQOISBRGBALY"; // only for test
|
||||
|
||||
// Coordinate class (equivalent to koord struct in Go)
|
||||
class Coord {
|
||||
constructor(x, y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
lessThan(other) {
|
||||
if (this.y > other.y) {
|
||||
return false;
|
||||
}
|
||||
if (this.y < other.y) {
|
||||
return true;
|
||||
}
|
||||
if (this.x < other.x) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
equalTo(other) {
|
||||
return this.x === other.x && this.y === other.y;
|
||||
}
|
||||
}
|
||||
|
||||
// Convert square to encryption and decryption maps
|
||||
function squareToMaps(square) {
|
||||
const encryptMap = new Map();
|
||||
const decryptMap = new Map();
|
||||
|
||||
for (let x = 0; x < square.length; x++) {
|
||||
for (let y = 0; y < square[x].length; y++) {
|
||||
const value = square[x][y];
|
||||
const coord = new Coord(x, y);
|
||||
|
||||
// For encryption map, use character as key
|
||||
encryptMap.set(value, coord);
|
||||
|
||||
// For decryption map, use coordinate string as key
|
||||
// (JavaScript Maps can't use objects as keys directly, so convert to string)
|
||||
decryptMap.set(`${x},${y}`, value);
|
||||
}
|
||||
}
|
||||
|
||||
return { encryptMap, decryptMap };
|
||||
}
|
||||
|
||||
// Remove spaces and non-valid characters
|
||||
function removeSpace(text, encryptMap) {
|
||||
const upper = text.toUpperCase().replace(/\s/g, '');
|
||||
let result = '';
|
||||
|
||||
for (const char of upper) {
|
||||
if (encryptMap.has(char)) {
|
||||
result += char;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Replace 'J' with 'I' (for specific Polybius square implementations)
|
||||
function removeSpaceI(text) {
|
||||
const upper = text.toUpperCase();
|
||||
let result = '';
|
||||
|
||||
for (const char of upper) {
|
||||
// Use only ASCII characters from A to Z
|
||||
if (char >= 'A' && char <= 'Z') {
|
||||
result += char === 'J' ? 'I' : char;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Encrypt using ADFGVX cipher
|
||||
function encrypt(text, encryptMap, decryptMap) {
|
||||
text = removeSpace(text, encryptMap);
|
||||
|
||||
const row0 = [];
|
||||
const row1 = [];
|
||||
|
||||
// Get coordinates for each character
|
||||
for (const char of text) {
|
||||
const coord = encryptMap.get(char);
|
||||
row0.push(coord.x);
|
||||
row1.push(coord.y);
|
||||
}
|
||||
|
||||
// Combine coordinates
|
||||
const combined = [...row0, ...row1];
|
||||
|
||||
let result = '';
|
||||
// Convert pairs of coordinates back to characters
|
||||
for (let i = 0; i < combined.length; i += 2) {
|
||||
const key = `${combined[i]},${combined[i+1]}`;
|
||||
result += decryptMap.get(key);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Decrypt using ADFGVX cipher
|
||||
function decrypt(text, encryptMap, decryptMap) {
|
||||
text = removeSpace(text, encryptMap);
|
||||
|
||||
const coords = [];
|
||||
|
||||
// Get coordinates for each character
|
||||
for (const char of text) {
|
||||
coords.push(encryptMap.get(char));
|
||||
}
|
||||
|
||||
// Extract x and y values
|
||||
const flatCoords = [];
|
||||
for (const coord of coords) {
|
||||
flatCoords.push(coord.x);
|
||||
flatCoords.push(coord.y);
|
||||
}
|
||||
|
||||
const half = Math.floor(flatCoords.length / 2);
|
||||
const firstHalf = flatCoords.slice(0, half);
|
||||
const secondHalf = flatCoords.slice(half);
|
||||
|
||||
let result = '';
|
||||
|
||||
// Recombine coordinates to get original text
|
||||
for (let i = 0; i < firstHalf.length; i++) {
|
||||
const key = `${firstHalf[i]},${secondHalf[i]}`;
|
||||
result += decryptMap.get(key);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// Main function to test
|
||||
function main() {
|
||||
// Test with Rosetta square
|
||||
let { encryptMap, decryptMap } = squareToMaps(squareRosetta);
|
||||
|
||||
console.log("From Rosetta Code");
|
||||
console.log("original:\t", textRosetta);
|
||||
let encoded = encrypt(textRosetta, encryptMap, decryptMap);
|
||||
console.log("encoded:\t", encoded);
|
||||
let decoded = decrypt(encoded, encryptMap, decryptMap);
|
||||
console.log("and back:\t", decoded);
|
||||
|
||||
// Test with Wikipedia square
|
||||
({ encryptMap, decryptMap } = squareToMaps(squareWikipedia));
|
||||
|
||||
console.log("\nFrom Wikipedia");
|
||||
console.log("original:\t", textWikipedia);
|
||||
encoded = encrypt(textWikipedia, encryptMap, decryptMap);
|
||||
console.log("encoded:\t", encoded);
|
||||
decoded = decrypt(encoded, encryptMap, decryptMap);
|
||||
console.log("and back:\t", decoded);
|
||||
|
||||
// Test with longer text
|
||||
console.log("\nFrom Rosetta Code (longer text)");
|
||||
console.log("original:\t", textTest);
|
||||
encoded = encrypt(textTest, encryptMap, decryptMap);
|
||||
console.log("encoded:\t", encoded);
|
||||
// Note: If the text has an odd number of letters, the algorithm doesn't work!
|
||||
decoded = decrypt(encoded, encryptMap, decryptMap);
|
||||
console.log("and back:\t", decoded);
|
||||
}
|
||||
|
||||
// Run the main function
|
||||
main();
|
||||
125
Task/Bifid-cipher/Rust/bifid-cipher.rs
Normal file
125
Task/Bifid-cipher/Rust/bifid-cipher.rs
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
type Point = (i32, i32);
|
||||
|
||||
|
||||
struct Bifid {
|
||||
grid: Vec<Vec<char>>,
|
||||
coordinates: HashMap<char, Point>,
|
||||
n: i32,
|
||||
}
|
||||
|
||||
impl Bifid {
|
||||
pub fn new(n: i32, text: &str) -> Result<Self, String> {
|
||||
if (text.len() as i32) != n * n {
|
||||
return Err("Incorrect length of text".to_string());
|
||||
}
|
||||
|
||||
let mut grid = vec![vec!['\0'; n as usize]; n as usize];
|
||||
let mut coordinates: HashMap<char, Point> = HashMap::new();
|
||||
|
||||
let mut row: i32 = 0;
|
||||
let mut col: i32 = 0;
|
||||
|
||||
for ch in text.chars() {
|
||||
grid[row as usize][col as usize] = ch;
|
||||
coordinates.insert(ch, (row, col));
|
||||
|
||||
col += 1;
|
||||
if col == n {
|
||||
col = 0;
|
||||
row += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if n == 5 {
|
||||
if let Some(&i_coords) = coordinates.get(&'I') {
|
||||
coordinates.insert('J', i_coords);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Bifid {
|
||||
grid,
|
||||
coordinates,
|
||||
n,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn encrypt(&self, text: &str) -> String {
|
||||
let mut row_one: Vec<i32> = Vec::new();
|
||||
let mut row_two: Vec<i32> = Vec::new();
|
||||
|
||||
for ch in text.chars() {
|
||||
if let Some(coordinate) = self.coordinates.get(&ch) {
|
||||
row_one.push(coordinate.0);
|
||||
row_two.push(coordinate.1);
|
||||
}
|
||||
}
|
||||
|
||||
row_one.extend(row_two.iter());
|
||||
let mut result = String::new();
|
||||
for i in (0..row_one.len() - 1).step_by(2) {
|
||||
result.push(self.grid[row_one[i] as usize][row_one[i + 1] as usize]);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub fn decrypt(&self, text: &str) -> String {
|
||||
let mut row: Vec<i32> = Vec::new();
|
||||
for ch in text.chars() {
|
||||
if let Some(coordinate) = self.coordinates.get(&ch) {
|
||||
row.push(coordinate.0);
|
||||
row.push(coordinate.1);
|
||||
}
|
||||
}
|
||||
|
||||
let middle = row.len() / 2;
|
||||
let row_one: Vec<i32> = row[..middle].to_vec();
|
||||
let row_two: Vec<i32> = row[middle..].to_vec();
|
||||
|
||||
let mut result = String::new();
|
||||
for i in 0..middle {
|
||||
result.push(self.grid[row_one[i] as usize][row_two[i] as usize]);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
pub fn display(&self) {
|
||||
for row in &self.grid {
|
||||
for ch in row {
|
||||
print!("{} ", ch);
|
||||
}
|
||||
println!();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run_test(bifid: &Bifid, message: &str) {
|
||||
println!("Using Polybius square:");
|
||||
bifid.display();
|
||||
println!("Message: {}", message);
|
||||
let encrypted = bifid.encrypt(message);
|
||||
println!("Encrypted: {}", encrypted);
|
||||
let decrypted = bifid.decrypt(&encrypted);
|
||||
println!("Decrypted: {}", decrypted);
|
||||
println!();
|
||||
}
|
||||
|
||||
fn main() -> Result<(), String> {
|
||||
let message1 = "ATTACKATDAWN";
|
||||
let message2 = "FLEEATONCE";
|
||||
let message3 = "THEINVASIONWILLSTARTONTHEFIRSTOFJANUARY";
|
||||
|
||||
let bifid1 = Bifid::new(5, "ABCDEFGHIKLMNOPQRSTUVWXYZ")?;
|
||||
let bifid2 = Bifid::new(5, "BGWKZQPNDSIOAXEFCLUMTHYVR")?;
|
||||
|
||||
run_test(&bifid1, message1);
|
||||
run_test(&bifid2, message2);
|
||||
run_test(&bifid2, message1);
|
||||
run_test(&bifid1, message2);
|
||||
|
||||
let bifid3 = Bifid::new(6, "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")?;
|
||||
run_test(&bifid3, message3);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue