]> git.lizzy.rs Git - rust.git/blob - src/librand/lib.rs
Bump version to 0.10
[rust.git] / src / librand / lib.rs
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /*!
12 Utilities for random number generation
13
14 The key functions are `random()` and `Rng::gen()`. These are polymorphic
15 and so can be used to generate any type that implements `Rand`. Type inference
16 means that often a simple call to `rand::random()` or `rng.gen()` will
17 suffice, but sometimes an annotation is required, e.g. `rand::random::<f64>()`.
18
19 See the `distributions` submodule for sampling random numbers from
20 distributions like normal and exponential.
21
22 # Task-local RNG
23
24 There is built-in support for a RNG associated with each task stored
25 in task-local storage. This RNG can be accessed via `task_rng`, or
26 used implicitly via `random`. This RNG is normally randomly seeded
27 from an operating-system source of randomness, e.g. `/dev/urandom` on
28 Unix systems, and will automatically reseed itself from this source
29 after generating 32 KiB of random data.
30
31 # Cryptographic security
32
33 An application that requires random numbers for cryptographic purposes
34 should prefer `OSRng`, which reads randomness from one of the source
35 that the operating system provides (e.g. `/dev/urandom` on
36 Unixes). The other random number generators provided by this module
37 are either known to be insecure (`XorShiftRng`), or are not verified
38 to be secure (`IsaacRng`, `Isaac64Rng` and `StdRng`).
39
40 *Note*: on Linux, `/dev/random` is more secure than `/dev/urandom`,
41 but it is a blocking RNG, and will wait until it has determined that
42 it has collected enough entropy to fulfill a request for random
43 data. It can be used with the `Rng` trait provided by this module by
44 opening the file and passing it to `reader::ReaderRng`. Since it
45 blocks, `/dev/random` should only be used to retrieve small amounts of
46 randomness.
47
48 # Examples
49
50 ```rust
51 use rand::Rng;
52
53 let mut rng = rand::task_rng();
54 if rng.gen() { // bool
55     println!("int: {}, uint: {}", rng.gen::<int>(), rng.gen::<uint>())
56 }
57 ```
58
59 ```rust
60 let tuple_ptr = rand::random::<~(f64, char)>();
61 println!("{:?}", tuple_ptr)
62 ```
63 */
64
65 #![crate_id = "rand#0.10"]
66 #![license = "MIT/ASL2"]
67 #![crate_type = "dylib"]
68 #![crate_type = "rlib"]
69 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk.png",
70        html_favicon_url = "http://www.rust-lang.org/favicon.ico",
71        html_root_url = "http://static.rust-lang.org/doc/master")]
72
73 #![feature(macro_rules, managed_boxes, phase)]
74
75 #[cfg(test)]
76 #[phase(syntax, link)] extern crate log;
77
78 use std::cast;
79 use std::kinds::marker;
80 use std::local_data;
81 use std::str;
82 use std::slice;
83
84 pub use isaac::{IsaacRng, Isaac64Rng};
85 pub use os::OSRng;
86
87 use distributions::{Range, IndependentSample};
88 use distributions::range::SampleRange;
89
90 pub mod distributions;
91 pub mod isaac;
92 pub mod os;
93 pub mod reader;
94 pub mod reseeding;
95 mod rand_impls;
96
97 /// A type that can be randomly generated using an `Rng`.
98 pub trait Rand {
99     /// Generates a random instance of this type using the specified source of
100     /// randomness.
101     fn rand<R: Rng>(rng: &mut R) -> Self;
102 }
103
104 /// A random number generator.
105 pub trait Rng {
106     /// Return the next random u32.
107     ///
108     /// This rarely needs to be called directly, prefer `r.gen()` to
109     /// `r.next_u32()`.
110     // FIXME #7771: Should be implemented in terms of next_u64
111     fn next_u32(&mut self) -> u32;
112
113     /// Return the next random u64.
114     ///
115     /// By default this is implemented in terms of `next_u32`. An
116     /// implementation of this trait must provide at least one of
117     /// these two methods. Similarly to `next_u32`, this rarely needs
118     /// to be called directly, prefer `r.gen()` to `r.next_u64()`.
119     fn next_u64(&mut self) -> u64 {
120         (self.next_u32() as u64 << 32) | (self.next_u32() as u64)
121     }
122
123     /// Fill `dest` with random data.
124     ///
125     /// This has a default implementation in terms of `next_u64` and
126     /// `next_u32`, but should be overridden by implementations that
127     /// offer a more efficient solution than just calling those
128     /// methods repeatedly.
129     ///
130     /// This method does *not* have a requirement to bear any fixed
131     /// relationship to the other methods, for example, it does *not*
132     /// have to result in the same output as progressively filling
133     /// `dest` with `self.gen::<u8>()`, and any such behaviour should
134     /// not be relied upon.
135     ///
136     /// This method should guarantee that `dest` is entirely filled
137     /// with new data, and may fail if this is impossible
138     /// (e.g. reading past the end of a file that is being used as the
139     /// source of randomness).
140     ///
141     /// # Example
142     ///
143     /// ```rust
144     /// use rand::{task_rng, Rng};
145     ///
146     /// let mut v = [0u8, .. 13579];
147     /// task_rng().fill_bytes(v);
148     /// println!("{:?}", v);
149     /// ```
150     fn fill_bytes(&mut self, dest: &mut [u8]) {
151         // this could, in theory, be done by transmuting dest to a
152         // [u64], but this is (1) likely to be undefined behaviour for
153         // LLVM, (2) has to be very careful about alignment concerns,
154         // (3) adds more `unsafe` that needs to be checked, (4)
155         // probably doesn't give much performance gain if
156         // optimisations are on.
157         let mut count = 0;
158         let mut num = 0;
159         for byte in dest.mut_iter() {
160             if count == 0 {
161                 // we could micro-optimise here by generating a u32 if
162                 // we only need a few more bytes to fill the vector
163                 // (i.e. at most 4).
164                 num = self.next_u64();
165                 count = 8;
166             }
167
168             *byte = (num & 0xff) as u8;
169             num >>= 8;
170             count -= 1;
171         }
172     }
173
174     /// Return a random value of a `Rand` type.
175     ///
176     /// # Example
177     ///
178     /// ```rust
179     /// use rand::{task_rng, Rng};
180     ///
181     /// let mut rng = task_rng();
182     /// let x: uint = rng.gen();
183     /// println!("{}", x);
184     /// println!("{:?}", rng.gen::<(f64, bool)>());
185     /// ```
186     #[inline(always)]
187     fn gen<T: Rand>(&mut self) -> T {
188         Rand::rand(self)
189     }
190
191     /// Return a random vector of the specified length.
192     ///
193     /// # Example
194     ///
195     /// ```rust
196     /// use rand::{task_rng, Rng};
197     ///
198     /// let mut rng = task_rng();
199     /// let x: ~[uint] = rng.gen_vec(10);
200     /// println!("{:?}", x);
201     /// println!("{:?}", rng.gen_vec::<(f64, bool)>(5));
202     /// ```
203     fn gen_vec<T: Rand>(&mut self, len: uint) -> ~[T] {
204         slice::from_fn(len, |_| self.gen())
205     }
206
207     /// Generate a random value in the range [`low`, `high`). Fails if
208     /// `low >= high`.
209     ///
210     /// This is a convenience wrapper around
211     /// `distributions::Range`. If this function will be called
212     /// repeatedly with the same arguments, one should use `Range`, as
213     /// that will amortize the computations that allow for perfect
214     /// uniformity, as they only happen on initialization.
215     ///
216     /// # Example
217     ///
218     /// ```rust
219     /// use rand::{task_rng, Rng};
220     ///
221     /// let mut rng = task_rng();
222     /// let n: uint = rng.gen_range(0u, 10);
223     /// println!("{}", n);
224     /// let m: f64 = rng.gen_range(-40.0, 1.3e5);
225     /// println!("{}", m);
226     /// ```
227     fn gen_range<T: Ord + SampleRange>(&mut self, low: T, high: T) -> T {
228         assert!(low < high, "Rng.gen_range called with low >= high");
229         Range::new(low, high).ind_sample(self)
230     }
231
232     /// Return a bool with a 1 in n chance of true
233     ///
234     /// # Example
235     ///
236     /// ```rust
237     /// use rand::{task_rng, Rng};
238     ///
239     /// let mut rng = task_rng();
240     /// println!("{:b}", rng.gen_weighted_bool(3));
241     /// ```
242     fn gen_weighted_bool(&mut self, n: uint) -> bool {
243         n == 0 || self.gen_range(0, n) == 0
244     }
245
246     /// Return a random string of the specified length composed of
247     /// A-Z,a-z,0-9.
248     ///
249     /// # Example
250     ///
251     /// ```rust
252     /// use rand::{task_rng, Rng};
253     ///
254     /// println!("{}", task_rng().gen_ascii_str(10));
255     /// ```
256     fn gen_ascii_str(&mut self, len: uint) -> ~str {
257         static GEN_ASCII_STR_CHARSET: &'static [u8] = bytes!("ABCDEFGHIJKLMNOPQRSTUVWXYZ\
258                                                              abcdefghijklmnopqrstuvwxyz\
259                                                              0123456789");
260         let mut s = str::with_capacity(len);
261         for _ in range(0, len) {
262             s.push_char(self.choose(GEN_ASCII_STR_CHARSET) as char)
263         }
264         s
265     }
266
267     /// Choose an item randomly, failing if `values` is empty.
268     fn choose<T: Clone>(&mut self, values: &[T]) -> T {
269         self.choose_option(values).expect("Rng.choose: `values` is empty").clone()
270     }
271
272     /// Choose `Some(&item)` randomly, returning `None` if values is
273     /// empty.
274     ///
275     /// # Example
276     ///
277     /// ```rust
278     /// use rand::{task_rng, Rng};
279     ///
280     /// let choices = [1, 2, 4, 8, 16, 32];
281     /// let mut rng = task_rng();
282     /// println!("{:?}", rng.choose_option(choices));
283     /// println!("{:?}", rng.choose_option(choices.slice_to(0)));
284     /// ```
285     fn choose_option<'a, T>(&mut self, values: &'a [T]) -> Option<&'a T> {
286         if values.is_empty() {
287             None
288         } else {
289             Some(&values[self.gen_range(0u, values.len())])
290         }
291     }
292
293     /// Shuffle a vec
294     ///
295     /// # Example
296     ///
297     /// ```rust
298     /// use rand::{task_rng, Rng};
299     ///
300     /// println!("{:?}", task_rng().shuffle(~[1,2,3]));
301     /// ```
302     fn shuffle<T>(&mut self, values: ~[T]) -> ~[T] {
303         let mut v = values;
304         self.shuffle_mut(v);
305         v
306     }
307
308     /// Shuffle a mutable vector in place.
309     ///
310     /// # Example
311     ///
312     /// ```rust
313     /// use rand::{task_rng, Rng};
314     ///
315     /// let mut rng = task_rng();
316     /// let mut y = [1,2,3];
317     /// rng.shuffle_mut(y);
318     /// println!("{:?}", y);
319     /// rng.shuffle_mut(y);
320     /// println!("{:?}", y);
321     /// ```
322     fn shuffle_mut<T>(&mut self, values: &mut [T]) {
323         let mut i = values.len();
324         while i >= 2u {
325             // invariant: elements with index >= i have been locked in place.
326             i -= 1u;
327             // lock element i in place.
328             values.swap(i, self.gen_range(0u, i + 1u));
329         }
330     }
331
332     /// Randomly sample up to `n` elements from an iterator.
333     ///
334     /// # Example
335     ///
336     /// ```rust
337     /// use rand::{task_rng, Rng};
338     ///
339     /// let mut rng = task_rng();
340     /// let sample = rng.sample(range(1, 100), 5);
341     /// println!("{:?}", sample);
342     /// ```
343     fn sample<A, T: Iterator<A>>(&mut self, iter: T, n: uint) -> ~[A] {
344         let mut reservoir : ~[A] = slice::with_capacity(n);
345         for (i, elem) in iter.enumerate() {
346             if i < n {
347                 reservoir.push(elem);
348                 continue
349             }
350
351             let k = self.gen_range(0, i + 1);
352             if k < reservoir.len() {
353                 reservoir[k] = elem
354             }
355         }
356         reservoir
357     }
358 }
359
360 /// A random number generator that can be explicitly seeded to produce
361 /// the same stream of randomness multiple times.
362 pub trait SeedableRng<Seed>: Rng {
363     /// Reseed an RNG with the given seed.
364     ///
365     /// # Example
366     ///
367     /// ```rust
368     /// use rand::{Rng, SeedableRng, StdRng};
369     ///
370     /// let mut rng: StdRng = SeedableRng::from_seed(&[1, 2, 3, 4]);
371     /// println!("{}", rng.gen::<f64>());
372     /// rng.reseed([5, 6, 7, 8]);
373     /// println!("{}", rng.gen::<f64>());
374     /// ```
375     fn reseed(&mut self, Seed);
376
377     /// Create a new RNG with the given seed.
378     ///
379     /// # Example
380     ///
381     /// ```rust
382     /// use rand::{Rng, SeedableRng, StdRng};
383     ///
384     /// let mut rng: StdRng = SeedableRng::from_seed(&[1, 2, 3, 4]);
385     /// println!("{}", rng.gen::<f64>());
386     /// ```
387     fn from_seed(seed: Seed) -> Self;
388 }
389
390 /// Create a random number generator with a default algorithm and seed.
391 ///
392 /// It returns the strongest `Rng` algorithm currently implemented in
393 /// pure Rust. If you require a specifically seeded `Rng` for
394 /// consistency over time you should pick one algorithm and create the
395 /// `Rng` yourself.
396 ///
397 /// This is a very expensive operation as it has to read randomness
398 /// from the operating system and use this in an expensive seeding
399 /// operation. If one does not require high performance generation of
400 /// random numbers, `task_rng` and/or `random` may be more
401 /// appropriate.
402 #[deprecated="use `task_rng` or `StdRng::new`"]
403 pub fn rng() -> StdRng {
404     StdRng::new()
405 }
406
407 /// The standard RNG. This is designed to be efficient on the current
408 /// platform.
409 #[cfg(not(target_word_size="64"))]
410 pub struct StdRng { priv rng: IsaacRng }
411
412 /// The standard RNG. This is designed to be efficient on the current
413 /// platform.
414 #[cfg(target_word_size="64")]
415 pub struct StdRng { priv rng: Isaac64Rng }
416
417 impl StdRng {
418     /// Create a randomly seeded instance of `StdRng`.
419     ///
420     /// This is a very expensive operation as it has to read
421     /// randomness from the operating system and use this in an
422     /// expensive seeding operation. If one is only generating a small
423     /// number of random numbers, or doesn't need the utmost speed for
424     /// generating each number, `task_rng` and/or `random` may be more
425     /// appropriate.
426     #[cfg(not(target_word_size="64"))]
427     pub fn new() -> StdRng {
428         StdRng { rng: IsaacRng::new() }
429     }
430     /// Create a randomly seeded instance of `StdRng`.
431     ///
432     /// This is a very expensive operation as it has to read
433     /// randomness from the operating system and use this in an
434     /// expensive seeding operation. If one is only generating a small
435     /// number of random numbers, or doesn't need the utmost speed for
436     /// generating each number, `task_rng` and/or `random` may be more
437     /// appropriate.
438     #[cfg(target_word_size="64")]
439     pub fn new() -> StdRng {
440         StdRng { rng: Isaac64Rng::new() }
441     }
442 }
443
444 impl Rng for StdRng {
445     #[inline]
446     fn next_u32(&mut self) -> u32 {
447         self.rng.next_u32()
448     }
449
450     #[inline]
451     fn next_u64(&mut self) -> u64 {
452         self.rng.next_u64()
453     }
454 }
455
456 impl<'a> SeedableRng<&'a [uint]> for StdRng {
457     fn reseed(&mut self, seed: &'a [uint]) {
458         // the internal RNG can just be seeded from the above
459         // randomness.
460         self.rng.reseed(unsafe {cast::transmute(seed)})
461     }
462
463     fn from_seed(seed: &'a [uint]) -> StdRng {
464         StdRng { rng: SeedableRng::from_seed(unsafe {cast::transmute(seed)}) }
465     }
466 }
467
468 /// Create a weak random number generator with a default algorithm and seed.
469 ///
470 /// It returns the fastest `Rng` algorithm currently available in Rust without
471 /// consideration for cryptography or security. If you require a specifically
472 /// seeded `Rng` for consistency over time you should pick one algorithm and
473 /// create the `Rng` yourself.
474 ///
475 /// This will read randomness from the operating system to seed the
476 /// generator.
477 pub fn weak_rng() -> XorShiftRng {
478     XorShiftRng::new()
479 }
480
481 /// An Xorshift[1] random number
482 /// generator.
483 ///
484 /// The Xorshift algorithm is not suitable for cryptographic purposes
485 /// but is very fast. If you do not know for sure that it fits your
486 /// requirements, use a more secure one such as `IsaacRng` or `OSRng`.
487 ///
488 /// [1]: Marsaglia, George (July 2003). ["Xorshift
489 /// RNGs"](http://www.jstatsoft.org/v08/i14/paper). *Journal of
490 /// Statistical Software*. Vol. 8 (Issue 14).
491 pub struct XorShiftRng {
492     priv x: u32,
493     priv y: u32,
494     priv z: u32,
495     priv w: u32,
496 }
497
498 impl Rng for XorShiftRng {
499     #[inline]
500     fn next_u32(&mut self) -> u32 {
501         let x = self.x;
502         let t = x ^ (x << 11);
503         self.x = self.y;
504         self.y = self.z;
505         self.z = self.w;
506         let w = self.w;
507         self.w = w ^ (w >> 19) ^ (t ^ (t >> 8));
508         self.w
509     }
510 }
511
512 impl SeedableRng<[u32, .. 4]> for XorShiftRng {
513     /// Reseed an XorShiftRng. This will fail if `seed` is entirely 0.
514     fn reseed(&mut self, seed: [u32, .. 4]) {
515         assert!(!seed.iter().all(|&x| x == 0),
516                 "XorShiftRng.reseed called with an all zero seed.");
517
518         self.x = seed[0];
519         self.y = seed[1];
520         self.z = seed[2];
521         self.w = seed[3];
522     }
523
524     /// Create a new XorShiftRng. This will fail if `seed` is entirely 0.
525     fn from_seed(seed: [u32, .. 4]) -> XorShiftRng {
526         assert!(!seed.iter().all(|&x| x == 0),
527                 "XorShiftRng::from_seed called with an all zero seed.");
528
529         XorShiftRng {
530             x: seed[0],
531             y: seed[1],
532             z: seed[2],
533             w: seed[3]
534         }
535     }
536 }
537
538 impl XorShiftRng {
539     /// Create an xor shift random number generator with a random seed.
540     pub fn new() -> XorShiftRng {
541         let mut s = [0u8, ..16];
542         loop {
543             let mut r = OSRng::new();
544             r.fill_bytes(s);
545
546             if !s.iter().all(|x| *x == 0) {
547                 break;
548             }
549         }
550         let s: [u32, ..4] = unsafe { cast::transmute(s) };
551         SeedableRng::from_seed(s)
552     }
553 }
554
555 /// Controls how the task-local RNG is reseeded.
556 struct TaskRngReseeder;
557
558 impl reseeding::Reseeder<StdRng> for TaskRngReseeder {
559     fn reseed(&mut self, rng: &mut StdRng) {
560         *rng = StdRng::new();
561     }
562 }
563 static TASK_RNG_RESEED_THRESHOLD: uint = 32_768;
564 type TaskRngInner = reseeding::ReseedingRng<StdRng, TaskRngReseeder>;
565 /// The task-local RNG.
566 pub struct TaskRng {
567     // This points into TLS (specifically, it points to the endpoint
568     // of a ~ stored in TLS, to make it robust against TLS moving
569     // things internally) and so this struct cannot be legally
570     // transferred between tasks *and* it's unsafe to deallocate the
571     // RNG other than when a task is finished.
572     //
573     // The use of unsafe code here is OK if the invariants above are
574     // satisfied; and it allows us to avoid (unnecessarily) using a
575     // GC'd or RC'd pointer.
576     priv rng: *mut TaskRngInner,
577     priv marker: marker::NoSend,
578 }
579
580 // used to make space in TLS for a random number generator
581 local_data_key!(TASK_RNG_KEY: ~TaskRngInner)
582
583 /// Retrieve the lazily-initialized task-local random number
584 /// generator, seeded by the system. Intended to be used in method
585 /// chaining style, e.g. `task_rng().gen::<int>()`.
586 ///
587 /// The RNG provided will reseed itself from the operating system
588 /// after generating a certain amount of randomness.
589 ///
590 /// The internal RNG used is platform and architecture dependent, even
591 /// if the operating system random number generator is rigged to give
592 /// the same sequence always. If absolute consistency is required,
593 /// explicitly select an RNG, e.g. `IsaacRng` or `Isaac64Rng`.
594 pub fn task_rng() -> TaskRng {
595     local_data::get_mut(TASK_RNG_KEY, |rng| match rng {
596         None => {
597             let mut rng = ~reseeding::ReseedingRng::new(StdRng::new(),
598                                                         TASK_RNG_RESEED_THRESHOLD,
599                                                         TaskRngReseeder);
600             let ptr = &mut *rng as *mut TaskRngInner;
601
602             local_data::set(TASK_RNG_KEY, rng);
603
604             TaskRng { rng: ptr, marker: marker::NoSend }
605         }
606         Some(rng) => TaskRng { rng: &mut **rng, marker: marker::NoSend }
607     })
608 }
609
610 impl Rng for TaskRng {
611     fn next_u32(&mut self) -> u32 {
612         unsafe { (*self.rng).next_u32() }
613     }
614
615     fn next_u64(&mut self) -> u64 {
616         unsafe { (*self.rng).next_u64() }
617     }
618
619     #[inline]
620     fn fill_bytes(&mut self, bytes: &mut [u8]) {
621         unsafe { (*self.rng).fill_bytes(bytes) }
622     }
623 }
624
625 /// Generate a random value using the task-local random number
626 /// generator.
627 ///
628 /// # Example
629 ///
630 /// ```rust
631 /// use rand::random;
632 ///
633 /// if random() {
634 ///     let x = random();
635 ///     println!("{}", 2u * x);
636 /// } else {
637 ///     println!("{}", random::<f64>());
638 /// }
639 /// ```
640 #[inline]
641 pub fn random<T: Rand>() -> T {
642     task_rng().gen()
643 }
644
645 /// A wrapper for generating floating point numbers uniformly in the
646 /// open interval `(0,1)` (not including either endpoint).
647 ///
648 /// Use `Closed01` for the closed interval `[0,1]`, and the default
649 /// `Rand` implementation for `f32` and `f64` for the half-open
650 /// `[0,1)`.
651 ///
652 /// # Example
653 /// ```rust
654 /// use rand::{random, Open01};
655 ///
656 /// let Open01(val) = random::<Open01<f32>>();
657 /// println!("f32 from (0,1): {}", val);
658 /// ```
659 pub struct Open01<F>(F);
660
661 /// A wrapper for generating floating point numbers uniformly in the
662 /// closed interval `[0,1]` (including both endpoints).
663 ///
664 /// Use `Open01` for the closed interval `(0,1)`, and the default
665 /// `Rand` implementation of `f32` and `f64` for the half-open
666 /// `[0,1)`.
667 ///
668 /// # Example
669 /// ```rust
670 /// use rand::{random, Closed01};
671 ///
672 /// let Closed01(val) = random::<Closed01<f32>>();
673 /// println!("f32 from [0,1]: {}", val);
674 /// ```
675 pub struct Closed01<F>(F);
676
677 #[cfg(test)]
678 mod test {
679     use std::slice;
680     use super::{Rng, task_rng, random, OSRng, SeedableRng, StdRng};
681
682     struct ConstRng { i: u64 }
683     impl Rng for ConstRng {
684         fn next_u32(&mut self) -> u32 { self.i as u32 }
685         fn next_u64(&mut self) -> u64 { self.i }
686
687         // no fill_bytes on purpose
688     }
689
690     #[test]
691     fn test_fill_bytes_default() {
692         let mut r = ConstRng { i: 0x11_22_33_44_55_66_77_88 };
693
694         // check every remainder mod 8, both in small and big vectors.
695         let lengths = [0, 1, 2, 3, 4, 5, 6, 7,
696                        80, 81, 82, 83, 84, 85, 86, 87];
697         for &n in lengths.iter() {
698             let mut v = slice::from_elem(n, 0u8);
699             r.fill_bytes(v);
700
701             // use this to get nicer error messages.
702             for (i, &byte) in v.iter().enumerate() {
703                 if byte == 0 {
704                     fail!("byte {} of {} is zero", i, n)
705                 }
706             }
707         }
708     }
709
710     #[test]
711     fn test_gen_range() {
712         let mut r = task_rng();
713         for _ in range(0, 1000) {
714             let a = r.gen_range(-3i, 42);
715             assert!(a >= -3 && a < 42);
716             assert_eq!(r.gen_range(0, 1), 0);
717             assert_eq!(r.gen_range(-12, -11), -12);
718         }
719
720         for _ in range(0, 1000) {
721             let a = r.gen_range(10, 42);
722             assert!(a >= 10 && a < 42);
723             assert_eq!(r.gen_range(0, 1), 0);
724             assert_eq!(r.gen_range(3_000_000u, 3_000_001), 3_000_000);
725         }
726
727     }
728
729     #[test]
730     #[should_fail]
731     fn test_gen_range_fail_int() {
732         let mut r = task_rng();
733         r.gen_range(5i, -2);
734     }
735
736     #[test]
737     #[should_fail]
738     fn test_gen_range_fail_uint() {
739         let mut r = task_rng();
740         r.gen_range(5u, 2u);
741     }
742
743     #[test]
744     fn test_gen_f64() {
745         let mut r = task_rng();
746         let a = r.gen::<f64>();
747         let b = r.gen::<f64>();
748         debug!("{:?}", (a, b));
749     }
750
751     #[test]
752     fn test_gen_weighted_bool() {
753         let mut r = task_rng();
754         assert_eq!(r.gen_weighted_bool(0u), true);
755         assert_eq!(r.gen_weighted_bool(1u), true);
756     }
757
758     #[test]
759     fn test_gen_ascii_str() {
760         let mut r = task_rng();
761         debug!("{}", r.gen_ascii_str(10u));
762         debug!("{}", r.gen_ascii_str(10u));
763         debug!("{}", r.gen_ascii_str(10u));
764         assert_eq!(r.gen_ascii_str(0u).len(), 0u);
765         assert_eq!(r.gen_ascii_str(10u).len(), 10u);
766         assert_eq!(r.gen_ascii_str(16u).len(), 16u);
767     }
768
769     #[test]
770     fn test_gen_vec() {
771         let mut r = task_rng();
772         assert_eq!(r.gen_vec::<u8>(0u).len(), 0u);
773         assert_eq!(r.gen_vec::<u8>(10u).len(), 10u);
774         assert_eq!(r.gen_vec::<f64>(16u).len(), 16u);
775     }
776
777     #[test]
778     fn test_choose() {
779         let mut r = task_rng();
780         assert_eq!(r.choose([1, 1, 1]), 1);
781     }
782
783     #[test]
784     fn test_choose_option() {
785         let mut r = task_rng();
786         let v: &[int] = &[];
787         assert!(r.choose_option(v).is_none());
788
789         let i = 1;
790         let v = [1,1,1];
791         assert_eq!(r.choose_option(v), Some(&i));
792     }
793
794     #[test]
795     fn test_shuffle() {
796         let mut r = task_rng();
797         let empty: ~[int] = ~[];
798         assert_eq!(r.shuffle(~[]), empty);
799         assert_eq!(r.shuffle(~[1, 1, 1]), ~[1, 1, 1]);
800     }
801
802     #[test]
803     fn test_task_rng() {
804         let mut r = task_rng();
805         r.gen::<int>();
806         assert_eq!(r.shuffle(~[1, 1, 1]), ~[1, 1, 1]);
807         assert_eq!(r.gen_range(0u, 1u), 0u);
808     }
809
810     #[test]
811     fn test_random() {
812         // not sure how to test this aside from just getting some values
813         let _n : uint = random();
814         let _f : f32 = random();
815         let _o : Option<Option<i8>> = random();
816         let _many : ((),
817                      (~uint, @int, ~Option<~(@u32, ~(@bool,))>),
818                      (u8, i8, u16, i16, u32, i32, u64, i64),
819                      (f32, (f64, (f64,)))) = random();
820     }
821
822     #[test]
823     fn test_sample() {
824         let min_val = 1;
825         let max_val = 100;
826
827         let mut r = task_rng();
828         let vals = range(min_val, max_val).collect::<~[int]>();
829         let small_sample = r.sample(vals.iter(), 5);
830         let large_sample = r.sample(vals.iter(), vals.len() + 5);
831
832         assert_eq!(small_sample.len(), 5);
833         assert_eq!(large_sample.len(), vals.len());
834
835         assert!(small_sample.iter().all(|e| {
836             **e >= min_val && **e <= max_val
837         }));
838     }
839
840     #[test]
841     fn test_std_rng_seeded() {
842         let s = OSRng::new().gen_vec::<uint>(256);
843         let mut ra: StdRng = SeedableRng::from_seed(s.as_slice());
844         let mut rb: StdRng = SeedableRng::from_seed(s.as_slice());
845         assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
846     }
847
848     #[test]
849     fn test_std_rng_reseed() {
850         let s = OSRng::new().gen_vec::<uint>(256);
851         let mut r: StdRng = SeedableRng::from_seed(s.as_slice());
852         let string1 = r.gen_ascii_str(100);
853
854         r.reseed(s);
855
856         let string2 = r.gen_ascii_str(100);
857         assert_eq!(string1, string2);
858     }
859 }
860
861 #[cfg(test)]
862 static RAND_BENCH_N: u64 = 100;
863
864 #[cfg(test)]
865 mod bench {
866     extern crate test;
867     use self::test::BenchHarness;
868     use {XorShiftRng, StdRng, IsaacRng, Isaac64Rng, Rng, RAND_BENCH_N};
869     use std::mem::size_of;
870
871     #[bench]
872     fn rand_xorshift(bh: &mut BenchHarness) {
873         let mut rng = XorShiftRng::new();
874         bh.iter(|| {
875             for _ in range(0, RAND_BENCH_N) {
876                 rng.gen::<uint>();
877             }
878         });
879         bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
880     }
881
882     #[bench]
883     fn rand_isaac(bh: &mut BenchHarness) {
884         let mut rng = IsaacRng::new();
885         bh.iter(|| {
886             for _ in range(0, RAND_BENCH_N) {
887                 rng.gen::<uint>();
888             }
889         });
890         bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
891     }
892
893     #[bench]
894     fn rand_isaac64(bh: &mut BenchHarness) {
895         let mut rng = Isaac64Rng::new();
896         bh.iter(|| {
897             for _ in range(0, RAND_BENCH_N) {
898                 rng.gen::<uint>();
899             }
900         });
901         bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
902     }
903
904     #[bench]
905     fn rand_std(bh: &mut BenchHarness) {
906         let mut rng = StdRng::new();
907         bh.iter(|| {
908             for _ in range(0, RAND_BENCH_N) {
909                 rng.gen::<uint>();
910             }
911         });
912         bh.bytes = size_of::<uint>() as u64 * RAND_BENCH_N;
913     }
914
915     #[bench]
916     fn rand_shuffle_100(bh: &mut BenchHarness) {
917         let mut rng = XorShiftRng::new();
918         let x : &mut[uint] = [1,..100];
919         bh.iter(|| {
920             rng.shuffle_mut(x);
921         })
922     }
923 }