polybius
This commit is contained in:
@@ -1,14 +1,15 @@
|
|||||||
mod atbash;
|
mod atbash;
|
||||||
mod caesar;
|
mod caesar;
|
||||||
|
mod polybius_square;
|
||||||
mod util;
|
mod util;
|
||||||
|
|
||||||
fn main() -> anyhow::Result<()> {
|
fn main() -> anyhow::Result<()> {
|
||||||
let alphabet = "абвгдежзиклмнопрстуфхцчшщъыьэюя"
|
let alphabet = "пцукезщшгнхъф.ылоравд,жэюмитьб_счя!"
|
||||||
.chars()
|
.chars()
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let encoder = caesar::CaesarCipher::new(alphabet, 1)?;
|
let encoder = polybius_square::PolybiusSquareCipher::new(alphabet, 5, 7)?;
|
||||||
println!("{}", encoder.encode("абвгд")?);
|
println!("{}", encoder.encode("таина")?);
|
||||||
println!("{}", encoder.decode("бвгде")?);
|
println!("{}", encoder.decode("чэсыэ")?);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
73
src/polybius_square.rs
Normal file
73
src/polybius_square.rs
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
use crate::util;
|
||||||
|
|
||||||
|
pub struct PolybiusSquareCipher {
|
||||||
|
alphabet: Vec<char>,
|
||||||
|
rows: usize,
|
||||||
|
columns: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PolybiusSquareCipher {
|
||||||
|
pub fn new(
|
||||||
|
alphabet: impl Into<Vec<char>>,
|
||||||
|
columns: usize,
|
||||||
|
rows: usize,
|
||||||
|
) -> anyhow::Result<Self> {
|
||||||
|
let alphabet = alphabet.into();
|
||||||
|
util::verify_alphabet(&alphabet)?;
|
||||||
|
if rows * columns != alphabet.len() {
|
||||||
|
return Err(anyhow::anyhow!(
|
||||||
|
"rows * columns must equal the length of the alphabet"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self {
|
||||||
|
alphabet,
|
||||||
|
rows,
|
||||||
|
columns,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn encode(&self, input: &str) -> anyhow::Result<String> {
|
||||||
|
let mut output = String::with_capacity(input.len());
|
||||||
|
|
||||||
|
for c in input.chars() {
|
||||||
|
let index = self
|
||||||
|
.alphabet
|
||||||
|
.iter()
|
||||||
|
.position(|&x| x == c)
|
||||||
|
.ok_or(anyhow::anyhow!("invalid character"))?;
|
||||||
|
|
||||||
|
let row = index / self.columns;
|
||||||
|
let col = index % self.columns;
|
||||||
|
|
||||||
|
output.push(self.alphabet[((row + 1) % self.rows) * self.columns + col]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(output)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn decode(&self, input: &str) -> anyhow::Result<String> {
|
||||||
|
let mut output = String::with_capacity(input.len());
|
||||||
|
|
||||||
|
for c in input.chars() {
|
||||||
|
let index = self
|
||||||
|
.alphabet
|
||||||
|
.iter()
|
||||||
|
.position(|&x| x == c)
|
||||||
|
.ok_or(anyhow::anyhow!("invalid character"))?;
|
||||||
|
|
||||||
|
let mut row = index / self.columns;
|
||||||
|
let col = index % self.columns;
|
||||||
|
|
||||||
|
if row == 0 {
|
||||||
|
row = self.rows - 1;
|
||||||
|
} else {
|
||||||
|
row -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
output.push(self.alphabet[(row % self.rows) * self.columns + col]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(output)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user