25

I tried to compile the following code:

extern crate rand; // 0.6
use rand::Rng;

fn main() {
    rand::thread_rng()
        .gen_ascii_chars()
        .take(10)
        .collect::<String>();
}

but cargo build says:

warning: unused import: `rand::Rng`
 --> src/main.rs:2:5
  |
2 | use rand::Rng;
  |     ^^^^^^^^^
  |
  = note: #[warn(unused_imports)] on by default

error[E0599]: no method named `gen_ascii_chars` found for type `rand::prelude::ThreadRng` in the current scope
 --> src/main.rs:6:10
  |
6 |         .gen_ascii_chars()
  |          ^^^^^^^^^^^^^^^

The Rust compiler asks me to remove the use rand::Rng; clause, at the same time complaining that there is no gen_ascii_chars method. I would expect Rust to just use rand::Rng trait, and to not provide such a contradictory error messages. How can I go further from here?

Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
M. Clabaut
  • 761
  • 1
  • 6
  • 9

4 Answers4

41

As explained in the rand 0.5.0 docs, gen_ascii_chars is deprecated and you should use sample_iter(&Alphanumeric) instead.

use rand::{distributions::Alphanumeric, Rng}; // 0.8

fn main() {
    let s: String = rand::thread_rng()
        .sample_iter(&Alphanumeric)
        .take(7)
        .map(char::from)
        .collect();
    println!("{}", s);
}
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
M. Clabaut
  • 761
  • 1
  • 6
  • 9
15

With the introduction of rand 0.8.4, rand now contains DistString which contains a more efficient method of sampling a random alphanumeric string. Example from the rand docs:

use rand::distributions::{Alphanumeric, DistString};

let string = Alphanumeric.sample_string(&mut rand::thread_rng(), 16);
println!("{}", string);
Mari
  • 151
  • 2
  • 5
  • 1
    That works, thanks! Playground: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=b49c143c033c38cdf7575f7a0c609204 – Tim Abell Apr 13 '23 at 14:09
2

You can use random-string crate with your charset. You can install it by including random-string library in your Cargo.toml.

Take a look at the example:

// Import generate function
use random_string::generate;

// Your custom charset
let charset = "abcdefghijklmnopqrstuvwxyz";

// Syntax:
// random_string::generate(length, your_charset);

// Usage:
println!("{}", generate(6, charset));
Felierix
  • 179
  • 3
  • 12
1

An example with a custom charset and rand crate:

use rand::Rng;
use std::iter;

fn generate(len: usize) -> String {
    const CHARSET: &[u8] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    let mut rng = rand::thread_rng();
    let one_char = || CHARSET[rng.gen_range(0..CHARSET.len())] as char;
    iter::repeat_with(one_char).take(len).collect()
}
DenisKolodin
  • 13,501
  • 3
  • 62
  • 65