v1
This commit is contained in:
152
src/main.rs
Normal file
152
src/main.rs
Normal file
@@ -0,0 +1,152 @@
|
||||
use std::io::{self, Write};
|
||||
use std::time::Duration;
|
||||
|
||||
use rand::prelude::*;
|
||||
use tokio::time::sleep;
|
||||
|
||||
static CHARSET: [&str; 221] = [
|
||||
"!", "\"", "#", "$", "%", "&", "'", "(", ")", "*", "+", ",", "-", ".", "/", "0", "1", "2", "3",
|
||||
"4", "5", "6", "7", "8", "9", ",", ";", "<", "=", ">", "?", "@", "A", "B", "C", "D", "E", "F",
|
||||
"G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y",
|
||||
"Z", "[", "\\", "]", "^", "_", "`", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l",
|
||||
"m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "{", "-", "}", "~", "Ç",
|
||||
"ü", "é", "â", "ä", "à", "å", "ç", "ê", "ë", "è", "ï", "î", "ì", "Ä", "Å", "É", "æ", "Æ", "ô",
|
||||
"ö", "ò", "û", "ù", "ÿ", "Ö", "Ü", "¢", "£", "¥", "₧", "ƒ", "á", "í", "ó", "ú", "ñ", "Ñ", "ª",
|
||||
"º", "¿", "⌐", "¬", "½", "¼", "¡", "«", "»", "░", "▒", "▓", "│", "┤", "╡", "╢", "╖", "╕", "╣",
|
||||
"║", "╗", "╝", "╜", "╛", "┐", "└", "┴", "┬", "├", "─", "┼", "╞", "╟", "╚", "╔", "╩", "╦", "╠",
|
||||
"═", "╬", "╶", "╸", "╤", "╥", "╙", "╘", "╒", "╓", "╫", "╪", "┘", "┌", "█", "▄", "▌", "▐", "▀",
|
||||
"ʱ", "ß", "γ", "π", "Σ", "σ", "µ", "τ", "Φ", "Θ", "Ω", "δ", "∞", "φ", "ε", "∩", "≡", "±", "≥",
|
||||
"≤", "⌠", "⌠", "÷", "≈", "°", "∙", "·", "√", "ⁿ", "²", "■",
|
||||
];
|
||||
|
||||
struct Cipher {
|
||||
text: String,
|
||||
line_count: usize,
|
||||
mask: Vec<bool>,
|
||||
}
|
||||
|
||||
impl Cipher {
|
||||
async fn load(delay: u64) -> Self {
|
||||
let mut text = String::new();
|
||||
let stdin = io::stdin();
|
||||
let mut line_count = 0;
|
||||
|
||||
for line in stdin.lines() {
|
||||
if let Ok(line) = line {
|
||||
text += &line;
|
||||
text += "\n";
|
||||
Self::print_line(line.as_str(), delay).await;
|
||||
line_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
let mask = Self::get_mask(text.as_str());
|
||||
Cipher {
|
||||
text,
|
||||
line_count,
|
||||
mask,
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mask(lines: &str) -> Vec<bool> {
|
||||
let mut mask: Vec<bool> = Default::default();
|
||||
|
||||
for c in lines.chars() {
|
||||
match c {
|
||||
c if c.is_whitespace() => mask.push(true),
|
||||
_ => mask.push(false),
|
||||
}
|
||||
}
|
||||
|
||||
mask
|
||||
}
|
||||
|
||||
async fn print_line(line: &str, delay: u64) {
|
||||
for c in line.chars() {
|
||||
match c {
|
||||
c if c.is_whitespace() => print!("{c}"),
|
||||
_ => {
|
||||
let idx = rand::random_range(0..CHARSET.len());
|
||||
print!("{}", CHARSET[idx]);
|
||||
}
|
||||
}
|
||||
let _ = std::io::stdout().flush();
|
||||
if delay > 0 {
|
||||
sleep(Duration::from_millis(delay)).await;
|
||||
}
|
||||
}
|
||||
println!();
|
||||
}
|
||||
|
||||
fn reset(&self) {
|
||||
if self.line_count > 0 {
|
||||
print!("\x1b[{}F", self.line_count);
|
||||
}
|
||||
}
|
||||
|
||||
fn display(&self, update_prob: u32) {
|
||||
for (c, m) in self.text.chars().zip(self.mask.iter()) {
|
||||
match m {
|
||||
true => print!("{c}"),
|
||||
false => {
|
||||
if rand::random_range(0..100)<update_prob{
|
||||
let idx = rand::random_range(0..CHARSET.len());
|
||||
print!("{}", CHARSET[idx]);
|
||||
}
|
||||
else{
|
||||
print!("\x1b[1C");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let _ = std::io::stdout().flush();
|
||||
}
|
||||
|
||||
fn random_unmask(&mut self, num: usize) -> bool {
|
||||
let mut rng = rand::rng();
|
||||
let mut idx: Vec<usize> = self
|
||||
.mask
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter_map(|(i, m)| if *m { None } else { Some(i) })
|
||||
.collect();
|
||||
|
||||
for offset in 0..num {
|
||||
let selected: usize = rand::random_range(offset..idx.len());
|
||||
self.mask[idx[selected]] = true;
|
||||
idx[selected] = idx[offset];
|
||||
|
||||
if offset == (idx.len()-1){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let mut cipher = Cipher::load(10).await;
|
||||
|
||||
sleep(Duration::from_millis(1000)).await;
|
||||
|
||||
for _ in 0..20 {
|
||||
cipher.reset();
|
||||
cipher.display(100);
|
||||
sleep(Duration::from_millis(50)).await;
|
||||
}
|
||||
|
||||
loop {
|
||||
cipher.reset();
|
||||
cipher.display(20);
|
||||
sleep(Duration::from_millis(100)).await;
|
||||
|
||||
if cipher.random_unmask(10){
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
cipher.reset();
|
||||
cipher.display(100);
|
||||
}
|
||||
Reference in New Issue
Block a user