Pseudo-random number generator & password generator I've started learning Rust and decided to implement something on my own from scratch. I've implemented a PRNG and I use it to generate random passwords.
Project tree:
|   .gitignore
|   Cargo.lock
|   Cargo.toml
|
+---src
|       main.rs
|       password.rs
|       xorshift.rs
|

main.rs :
use std::io;

mod xorshift;
mod password;

fn main() {

    let length : u32;

    loop{
        let mut pass_leng_str = String::new();

        println!(&quot;Enter the length of wannable password: &quot;);

        io::stdin()
            .read_line(&amp;mut pass_leng_str)
            .expect(&quot;Faild to read the line&quot;);

        let pass_leng_str = pass_leng_str.trim();

        match pass_leng_str.parse::&lt;u32&gt;(){
            Ok(i) =&gt; {
                length = i;
                break;
            },
            Err(..) =&gt; {
                println!(&quot;Not a valid integer!&quot;); 
            },
        }
    }
    println!(&quot;Enter the characters you want to exclude: &quot;);

    let mut exclude = String::new();

    io::stdin()
        .read_line(&amp;mut exclude)
        .expect(&quot;Faild to read the line&quot;);
    
    let excluded : Vec&lt;char&gt; = exclude.chars().collect();

    println!(&quot;{}&quot;, password::rand_pass(length, excluded));

}

password.rs :
use super::xorshift;

pub static ASCII : [char; 69] = [
    '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',
    '1','2','3','4',
    '5','6','7','8',
    '9','0',
    '+','-','_','?','!','$','/',
];

pub fn rand_pass(pass_len : u32, excluded : Vec&lt;char&gt;)-&gt; String{
    let mut  password = String::new();
    for _i in 0..pass_len{
        let c : char = loop{
            let c = ASCII[xorshift::get_rand(69) as usize];
            if !excluded.contains(&amp;c){
                break c
            }
        };
        password.push(c);
    }

    password
}

xorshift.rs :
use std::time::UNIX_EPOCH;
use std::time::SystemTime;

pub fn get_rand(len : u128) -&gt; u128{
    let now = SystemTime::now();
    let from_unix = now.duration_since(UNIX_EPOCH).expect(&quot;Congrats on time travel!&quot;);
    let seed = from_unix.as_nanos();
    let x = seed;
    let x = x ^ seed &lt;&lt; 13;
    let x = x ^ x &gt;&gt;17;
    let x = x ^ x &lt;&lt;5;
    let x = x % len;
    x as u128
}
Welcome to Rust, and welcome to Code Review!
rustfmt &amp; clippy
Always run cargo fmt and cargo clippy first.  cargo fmt
formats your code according to the official Rust Style Guide, and
cargo clippy detects common mistakes and provides feedback on
improving your code (none in this case).
main.rs
The biggest problem with the main function is its structure.
Logically, the job of main is to:

read the length of the password;

read the excluded characters; and

output the generated password.


You spent so much code on the first step that it is hard to recognize
at a glance without being familiar with input loops.  For readability,
it is preferable to extract all of this into a function:
fn input_length() -&gt; usize {
    loop {
        eprintln!(&quot;Enter the length of password: &quot;);

        let mut length = String::new();
        io::stdin()
            .read_line(&amp;mut length)
            .expect(&quot;cannot read line&quot;);

        match length.trim().parse() {
            Ok(length) =&gt; return length,
            Err(_) =&gt; eprintln!(&quot;Error: invalid length\n&quot;),
        }
    }
}

Lengths are usually represented by usize in Rust to avoid type
casts, instead of u32.
It is recommended to define variables as close to their usage as
possible.
Personally, I would change all occurrences of println! to
eprintln! expect the one that actually prints the password, so that
the program can be easily used in an automated script by reading
stdout.
Moving on, we see that there is no need to extract all characters in
exclude, a String, into excluded, a Vec&lt;char&gt; (the naming can
be improved, by the way).  A String encodes the characters in UTF-8,
which is variable-length, so ASCII characters take up only 1 byte
each, whereas a sequence of chars always stores each character as 4
bytes.  Moreover, UTF-8 is specially constructed so that searching
requires only a linear scan and no computation of character
boundaries, so there is no performance gain.
password.rs
It shouldn't be the job of the password module to expose a constant
array containing ASCII characters.  A better name for ASCII may be
ALLOWED_CHARS.
The function rand_pass will often be called with the password::
prefix, so it is not necessary to repeat this information.  I would
name it generate.
Since the function does not consume excluded, take a &amp;[char], or
better, &amp;str parameter.  See Why is it discouraged to accept a
reference to a String (&amp;String), Vec (&amp;Vec), or Box (&amp;Box)
as a function argument?.
The function can be rewritten in a more logically straightforward
manner using iterators:
use std::iter;

pub fn generate(length: usize, excluded: &amp;str) -&gt; String {
    iter::repeat_with(generate_char)
        .filter(|c| !excluded.contains(&amp;c))
        .take(length)
        .collect()
}

where generate_char is a function Fn() -&gt; char that generates an
individual random character in the password, omitted for simplicity.
The intent is now clearer.
xorshift.rs
A better name for the module might be time_rng.
use declarations can be condensed:
use std::time::{SystemTime, UNIX_EPOCH};

A mutable variable is more readable to me here:
let mut x = seed;
x ^= (seed &lt;&lt; 13);
x ^= (x &gt;&gt; 17);
x ^= (x &lt;&lt; 5);
x % len

It is best to not count on the reader knowing the operator precedence
here.