|
|
|
#![allow(dead_code)]
|
|
|
|
|
|
|
|
extern crate getrandom;
|
|
|
|
|
|
|
|
use getrandom::*;
|
|
|
|
|
|
|
|
mod parse;
|
|
|
|
mod r#impl;
|
|
|
|
#[cfg(feature="plugin")] mod plugin;
|
|
|
|
|
|
|
|
const BYTES_BUFFER_SIZE: usize = 4096;
|
|
|
|
|
|
|
|
fn get<T>() -> Result<T, Error>
|
|
|
|
{
|
|
|
|
use core::mem::MaybeUninit;
|
|
|
|
let mut value: MaybeUninit<T> = MaybeUninit::uninit();
|
|
|
|
|
|
|
|
let value = unsafe {
|
|
|
|
let mut slice = std::slice::from_raw_parts_mut(value.as_mut_ptr() as *mut u8, std::mem::size_of::<T>());
|
|
|
|
populate(&mut slice)?;
|
|
|
|
|
|
|
|
value.assume_init()
|
|
|
|
};
|
|
|
|
|
|
|
|
Ok(value)
|
|
|
|
}
|
|
|
|
|
|
|
|
fn double() -> Result<f64, Error>
|
|
|
|
{
|
|
|
|
let long: i64 = get::<i64>()?;
|
|
|
|
|
|
|
|
Ok( ((long & ((1i64 << 53) - 1)) as f64) * (1_f64 / ((1_i64 << 53) as f64)))
|
|
|
|
}
|
|
|
|
|
|
|
|
fn populate(mut value: &mut [u8]) -> Result<(), Error>
|
|
|
|
{
|
|
|
|
getrandom(&mut value)?;
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn int(low: i32, high: i32) -> Result<i32, Error>
|
|
|
|
{
|
|
|
|
let value = double()?;
|
|
|
|
return Ok(low + (value * (high - low) as f64).floor() as i32);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn usage()
|
|
|
|
{
|
|
|
|
println!("Usage: rng --range <start> <end> [<repeat>]");
|
|
|
|
println!("Usage: rng --floor <start> <end> [<repeat>]");
|
|
|
|
println!("Usage: rng --round <start> <end> [<repeat>]");
|
|
|
|
println!("Usage: rng --ceil <start> <end> [<repeat>]");
|
|
|
|
println!("Usage: rng --of <opts...>");
|
|
|
|
println!("Usage: rng --shuffle <opts...>");
|
|
|
|
println!("Usage: rng --bytes <number>[k|m|g]");
|
|
|
|
}
|
|
|
|
|
|
|
|
fn range(args: &[String]) -> Result<(), Error>
|
|
|
|
{
|
|
|
|
if args.len() < 2 {
|
|
|
|
usage();
|
|
|
|
} else {
|
|
|
|
let start: f64 = args[0].parse().expect("Not a number (start).");
|
|
|
|
let end: f64 = args[1].parse().expect("Not a number (end).");
|
|
|
|
if args.len() >= 3 {
|
|
|
|
let repeat: usize = args[2].parse().expect("Not a valid number (repeat).");
|
|
|
|
|
|
|
|
r#impl::range(start,end,repeat)?;
|
|
|
|
} else {
|
|
|
|
r#impl::range(start,end,1)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn round(args: &[String]) -> Result<(), Error>
|
|
|
|
{
|
|
|
|
if args.len() < 2 {
|
|
|
|
usage();
|
|
|
|
} else {
|
|
|
|
let start: f64 = args[0].parse().expect("Not a number (start).");
|
|
|
|
let end: f64 = args[1].parse().expect("Not a number (end).");
|
|
|
|
if args.len() >= 3 {
|
|
|
|
let repeat: usize = args[2].parse().expect("Not a valid number (repeat).");
|
|
|
|
|
|
|
|
r#impl::round(start,end,repeat)?;
|
|
|
|
} else {
|
|
|
|
r#impl::round(start,end,1)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn ceil(args: &[String]) -> Result<(), Error>
|
|
|
|
{
|
|
|
|
if args.len() < 2 {
|
|
|
|
usage();
|
|
|
|
} else {
|
|
|
|
let start: f64 = args[0].parse().expect("Not a number (start).");
|
|
|
|
let end: f64 = args[1].parse().expect("Not a number (end).");
|
|
|
|
if args.len() >= 3 {
|
|
|
|
let repeat: usize = args[2].parse().expect("Not a valid number (repeat).");
|
|
|
|
|
|
|
|
r#impl::ceil(start,end,repeat)?;
|
|
|
|
} else {
|
|
|
|
r#impl::ceil(start,end,1)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn floor(args: &[String]) -> Result<(), Error>
|
|
|
|
{
|
|
|
|
if args.len() < 2 {
|
|
|
|
usage();
|
|
|
|
} else {
|
|
|
|
let start: f64 = args[0].parse().expect("Not a number (start).");
|
|
|
|
let end: f64 = args[1].parse().expect("Not a number (end).");
|
|
|
|
if args.len() >= 3 {
|
|
|
|
let repeat: usize = args[2].parse().expect("Not a valid number (repeat).");
|
|
|
|
|
|
|
|
r#impl::floor(start,end,repeat)?;
|
|
|
|
} else {
|
|
|
|
r#impl::floor(start,end,1)?;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn of(args: &[String]) -> Result<(), Error>
|
|
|
|
{
|
|
|
|
let max = args.len();
|
|
|
|
let int = int(0, max as i32)? as usize;
|
|
|
|
|
|
|
|
println!("{}", args[int]);
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn shuffle(args: &[String]) -> Result<(), Error>
|
|
|
|
{
|
|
|
|
let mut values: Vec<String> = args.to_vec();
|
|
|
|
|
|
|
|
for i in (1..args.len()).rev() {
|
|
|
|
let j = int(0, i as i32)? as usize;
|
|
|
|
|
|
|
|
values.swap(i, j);
|
|
|
|
}
|
|
|
|
|
|
|
|
for a in values.iter() {
|
|
|
|
println!("{}", a);
|
|
|
|
}
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn bytes(args: &[String]) -> Result<(), Error>
|
|
|
|
{
|
|
|
|
if args.len() < 1 {
|
|
|
|
usage();
|
|
|
|
} else {
|
|
|
|
let num = parse::bytes(&args[0]).expect("Failed to parse number of bytes") as usize;
|
|
|
|
|
|
|
|
if cfg!(feature="bytes-dynamic") {
|
|
|
|
let mut mem = Vec::with_capacity(num);
|
|
|
|
|
|
|
|
debug_assert_eq!(mem.capacity(), num);
|
|
|
|
// SAFETY: populating uninitialised memory with random data. There are no reads to the uninitialised data.
|
|
|
|
unsafe {
|
|
|
|
mem.set_len(num);
|
|
|
|
populate(&mut mem[..])?;
|
|
|
|
}
|
|
|
|
debug_assert_eq!(num, mem.len());
|
|
|
|
|
|
|
|
let stdout = std::io::stdout();
|
|
|
|
|
|
|
|
use std::io::Write;
|
|
|
|
stdout.lock().write_all(&mem[..]).expect("write error");
|
|
|
|
} else {
|
|
|
|
let mut buffer = [0u8; BYTES_BUFFER_SIZE];
|
|
|
|
let mut num = num;
|
|
|
|
let stdout = std::io::stdout();
|
|
|
|
let mut stdout = stdout.lock();
|
|
|
|
|
|
|
|
while num > 0 {
|
|
|
|
let w = std::cmp::min(num, BYTES_BUFFER_SIZE);
|
|
|
|
getrandom(&mut buffer[..w])?;
|
|
|
|
|
|
|
|
use std::io::Write;
|
|
|
|
stdout.write_all(&buffer[..w]).expect("write error");
|
|
|
|
num -= w;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn main() -> Result<(), Error> {
|
|
|
|
|
|
|
|
let args: Vec<String> = std::env::args().collect();
|
|
|
|
|
|
|
|
if args.len() < 2 {
|
|
|
|
usage();
|
|
|
|
Ok(())
|
|
|
|
} else {
|
|
|
|
match args[1].to_lowercase().as_str() {
|
|
|
|
"--range" => range(&args[2..])?,
|
|
|
|
"--round" => round(&args[2..])?,
|
|
|
|
"--ceil" => ceil(&args[2..])?,
|
|
|
|
"--floor" => floor(&args[2..])?,
|
|
|
|
"--of" => of(&args[2..])?,
|
|
|
|
"--shuffle" => shuffle(&args[2..])?,
|
|
|
|
"--bytes" => bytes(&args[2..])?,
|
|
|
|
_ => usage()
|
|
|
|
};
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|