diff --git a/src/libextra/bitv.rs b/src/libextra/bitv.rs
index 98f69425aee..4f8cd4d3308 100644
--- a/src/libextra/bitv.rs
+++ b/src/libextra/bitv.rs
@@ -1524,8 +1524,8 @@ mod tests {
     }
 
     fn rng() -> rand::IsaacRng {
-        let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
-        rand::IsaacRng::new_seeded(seed)
+        let seed = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 0];
+        rand::SeedableRng::from_seed(seed)
     }
 
     #[bench]
diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs
index ee7ba4a888b..66e1fd0c2c3 100644
--- a/src/libextra/treemap.rs
+++ b/src/libextra/treemap.rs
@@ -1013,7 +1013,7 @@ mod test_treemap {
         check_equal(ctrl, &map);
         assert!(map.find(&5).is_none());
 
-        let mut rng = rand::IsaacRng::new_seeded(&[42]);
+        let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(&[42]);
 
         do 3.times {
             do 90.times {
diff --git a/src/libstd/rand/isaac.rs b/src/libstd/rand/isaac.rs
index 534ebfb473b..6d338a922be 100644
--- a/src/libstd/rand/isaac.rs
+++ b/src/libstd/rand/isaac.rs
@@ -10,15 +10,10 @@
 
 //! The ISAAC random number generator.
 
-use rand::{seed, Rng};
-use iter::{Iterator, range, range_step};
+use rand::{seed, Rng, SeedableRng};
+use iter::{Iterator, range, range_step, Repeat};
 use option::{None, Some};
 
-use cast;
-use cmp;
-use sys;
-use vec;
-
 static RAND_SIZE_LEN: u32 = 8;
 static RAND_SIZE: u32 = 1 << RAND_SIZE_LEN;
 
@@ -38,30 +33,8 @@ pub struct IsaacRng {
 impl IsaacRng {
     /// Create an ISAAC random number generator with a random seed.
     pub fn new() -> IsaacRng {
-        IsaacRng::new_seeded(seed(RAND_SIZE as uint * 4))
-    }
-
-    /// Create an ISAAC random number generator with a seed. This can be any
-    /// length, although the maximum number of bytes used is 1024 and any more
-    /// will be silently ignored. A generator constructed with a given seed
-    /// will generate the same sequence of values as all other generators
-    /// constructed with the same seed.
-    pub fn new_seeded(seed: &[u8]) -> IsaacRng {
-        let mut rng = IsaacRng {
-            cnt: 0,
-            rsl: [0, .. RAND_SIZE],
-            mem: [0, .. RAND_SIZE],
-            a: 0, b: 0, c: 0
-        };
-
-        let array_size = sys::size_of_val(&rng.rsl);
-        let copy_length = cmp::min(array_size, seed.len());
-
-        // manually create a &mut [u8] slice of randrsl to copy into.
-        let dest = unsafe { cast::transmute((&mut rng.rsl, array_size)) };
-        vec::bytes::copy_memory(dest, seed, copy_length);
-        rng.init(true);
-        rng
+        let s = unsafe {seed::<u32>(RAND_SIZE as uint)};
+        SeedableRng::from_seed(s.as_slice())
     }
 
     /// Create an ISAAC random number generator using the default
@@ -197,6 +170,43 @@ impl Rng for IsaacRng {
     }
 }
 
+impl<'self> SeedableRng<&'self [u32]> for IsaacRng {
+    fn reseed(&mut self, seed: &'self [u32]) {
+        // make the seed into [seed[0], seed[1], ..., seed[seed.len()
+        // - 1], 0, 0, ...], to fill rng.rsl.
+        let seed_iter = seed.iter().map(|&x| x).chain(Repeat::new(0u32));
+
+        for (rsl_elem, seed_elem) in self.rsl.mut_iter().zip(seed_iter) {
+            *rsl_elem = seed_elem;
+        }
+        self.cnt = 0;
+        self.a = 0;
+        self.b = 0;
+        self.c = 0;
+
+        self.init(true);
+    }
+
+    /// Create an ISAAC random number generator with a seed. This can
+    /// be any length, although the maximum number of elements used is
+    /// 256 and any more will be silently ignored. A generator
+    /// constructed with a given seed will generate the same sequence
+    /// of values as all other generators constructed with that seed.
+    fn from_seed(seed: &'self [u32]) -> IsaacRng {
+        let mut rng = IsaacRng {
+            cnt: 0,
+            rsl: [0, .. RAND_SIZE],
+            mem: [0, .. RAND_SIZE],
+            a: 0, b: 0, c: 0
+        };
+
+        rng.reseed(seed);
+
+        rng
+    }
+}
+
+
 static RAND_SIZE_64_LEN: uint = 8;
 static RAND_SIZE_64: uint = 1 << RAND_SIZE_64_LEN;
 
@@ -218,31 +228,8 @@ impl Isaac64Rng {
     /// Create a 64-bit ISAAC random number generator with a random
     /// seed.
     pub fn new() -> Isaac64Rng {
-        Isaac64Rng::new_seeded(seed(RAND_SIZE_64 as uint * 8))
-    }
-
-    /// Create a 64-bit ISAAC random number generator with a
-    /// seed. This can be any length, although the maximum number of
-    /// bytes used is 2048 and any more will be silently ignored. A
-    /// generator constructed with a given seed will generate the same
-    /// sequence of values as all other generators constructed with
-    /// the same seed.
-    pub fn new_seeded(seed: &[u8]) -> Isaac64Rng {
-        let mut rng = Isaac64Rng {
-            cnt: 0,
-            rsl: [0, .. RAND_SIZE_64],
-            mem: [0, .. RAND_SIZE_64],
-            a: 0, b: 0, c: 0,
-        };
-
-        let array_size = sys::size_of_val(&rng.rsl);
-        let copy_length = cmp::min(array_size, seed.len());
-
-        // manually create a &mut [u8] slice of randrsl to copy into.
-        let dest = unsafe { cast::transmute((&mut rng.rsl, array_size)) };
-        vec::bytes::copy_memory(dest, seed, copy_length);
-        rng.init(true);
-        rng
+        let s = unsafe {seed::<u64>(RAND_SIZE_64)};
+        SeedableRng::from_seed(s.as_slice())
     }
 
     /// Create a 64-bit ISAAC random number generator using the
@@ -378,22 +365,58 @@ impl Rng for Isaac64Rng {
     }
 }
 
+impl<'self> SeedableRng<&'self [u64]> for Isaac64Rng {
+    fn reseed(&mut self, seed: &'self [u64]) {
+        // make the seed into [seed[0], seed[1], ..., seed[seed.len()
+        // - 1], 0, 0, ...], to fill rng.rsl.
+        let seed_iter = seed.iter().map(|&x| x).chain(Repeat::new(0u64));
+
+        for (rsl_elem, seed_elem) in self.rsl.mut_iter().zip(seed_iter) {
+            *rsl_elem = seed_elem;
+        }
+        self.cnt = 0;
+        self.a = 0;
+        self.b = 0;
+        self.c = 0;
+
+        self.init(true);
+    }
+
+    /// Create an ISAAC random number generator with a seed. This can
+    /// be any length, although the maximum number of elements used is
+    /// 256 and any more will be silently ignored. A generator
+    /// constructed with a given seed will generate the same sequence
+    /// of values as all other generators constructed with that seed.
+    fn from_seed(seed: &'self [u64]) -> Isaac64Rng {
+        let mut rng = Isaac64Rng {
+            cnt: 0,
+            rsl: [0, .. RAND_SIZE_64],
+            mem: [0, .. RAND_SIZE_64],
+            a: 0, b: 0, c: 0,
+        };
+        rng.reseed(seed);
+        rng
+    }
+}
+
 #[cfg(test)]
 mod test {
     use super::*;
-    use rand::{Rng, seed};
-    use option::{Option, Some};
+    use rand::{Rng, SeedableRng, seed};
+    use option::Some;
+    use iter::range;
+    use vec;
 
     #[test]
     fn test_rng_seeded() {
-        let seed = seed(1024);
-        let mut ra = IsaacRng::new_seeded(seed);
-        let mut rb = IsaacRng::new_seeded(seed);
+        let s = unsafe {seed::<u32>(256)};
+        let mut ra: IsaacRng = SeedableRng::from_seed(s.as_slice());
+        let mut rb: IsaacRng = SeedableRng::from_seed(s.as_slice());
         assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
 
-        let seed = seed(2048);
-        let mut ra = Isaac64Rng::new_seeded(seed);
-        let mut rb = Isaac64Rng::new_seeded(seed);
+        let s = unsafe {seed::<u64>(256)};
+        let mut ra: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
+        let mut rb: Isaac64Rng = SeedableRng::from_seed(s.as_slice());
         assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
     }
 
@@ -401,29 +424,59 @@ mod test {
     fn test_rng_seeded_custom_seed() {
         // much shorter than generated seeds which are 1024 & 2048
         // bytes resp.
-        let seed = [2u8, 32u8, 4u8, 32u8, 51u8];
-        let mut ra = IsaacRng::new_seeded(seed);
-        let mut rb = IsaacRng::new_seeded(seed);
+        let seed = &[2, 32, 4, 32, 51];
+        let mut ra: IsaacRng = SeedableRng::from_seed(seed);
+        let mut rb: IsaacRng = SeedableRng::from_seed(seed);
         assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
 
-        let mut ra = Isaac64Rng::new_seeded(seed);
-        let mut rb = Isaac64Rng::new_seeded(seed);
+        let seed = &[2, 32, 4, 32, 51];
+        let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
+        let mut rb: Isaac64Rng = SeedableRng::from_seed(seed);
         assert_eq!(ra.gen_ascii_str(100u), rb.gen_ascii_str(100u));
     }
 
     #[test]
-    fn test_rng_seeded_custom_seed2() {
-        let seed = [2u8, 32u8, 4u8, 32u8, 51u8];
-        let mut ra = IsaacRng::new_seeded(seed);
+    fn test_rng_32_true_values() {
+        let seed = &[2, 32, 4, 32, 51];
+        let mut ra: IsaacRng = SeedableRng::from_seed(seed);
         // Regression test that isaac is actually using the above vector
-        let r = ra.next_u32();
-        error2!("{:?}", r);
-        assert_eq!(r, 2935188040u32);
+        let v = vec::from_fn(10, |_| ra.next_u32());
+        assert_eq!(v,
+                   ~[447462228, 2081944040, 3163797308, 2379916134, 2377489184,
+                     1132373754, 536342443, 2995223415, 1265094839, 345325140]);
 
-        let mut ra = Isaac64Rng::new_seeded(seed);
+        let seed = &[500, -4000, 123456, 9876543, 1, 1, 1, 1, 1];
+        let mut rb: IsaacRng = SeedableRng::from_seed(seed);
+        // skip forward to the 10000th number
+        for _ in range(0, 10000) { rb.next_u32(); }
+
+        let v = vec::from_fn(10, |_| rb.next_u32());
+        assert_eq!(v,
+                   ~[612373032, 292987903, 1819311337, 3141271980, 422447569,
+                     310096395, 1083172510, 867909094, 2478664230, 2073577855]);
+    }
+    #[test]
+    fn test_rng_64_true_values() {
+        let seed = &[2, 32, 4, 32, 51];
+        let mut ra: Isaac64Rng = SeedableRng::from_seed(seed);
         // Regression test that isaac is actually using the above vector
-        let r = ra.next_u64();
-        error2!("{:?}", r);
-        assert!(r == 0 && r == 1); // FIXME: find true value
+        let v = vec::from_fn(10, |_| ra.next_u64());
+        assert_eq!(v,
+                   ~[15015576812873463115, 12461067598045625862, 14818626436142668771,
+                     5562406406765984441, 11813289907965514161, 13443797187798420053,
+                     6935026941854944442, 7750800609318664042, 14428747036317928637,
+                     14028894460301215947]);
+
+        let seed = &[500, -4000, 123456, 9876543, 1, 1, 1, 1, 1];
+        let mut rb: Isaac64Rng = SeedableRng::from_seed(seed);
+        // skip forward to the 10000th number
+        for _ in range(0, 10000) { rb.next_u64(); }
+
+        let v = vec::from_fn(10, |_| rb.next_u64());
+        assert_eq!(v,
+                   ~[13557216323596688637, 17060829581390442094, 4927582063811333743,
+                     2699639759356482270, 4819341314392384881, 6047100822963614452,
+                     11086255989965979163, 11901890363215659856, 5370800226050011580,
+                     16496463556025356451]);
     }
 }
diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs
index 9fb6863692b..64f266d0045 100644
--- a/src/libstd/rand/mod.rs
+++ b/src/libstd/rand/mod.rs
@@ -638,6 +638,42 @@ pub trait Rng {
     }
 }
 
+/// A random number generator that can be explicitly seeded to produce
+/// the same stream of randomness multiple times.
+pub trait SeedableRng<Seed>: Rng {
+    /// Reseed an RNG with the given seed.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use std::rand;
+    /// use std::rand::Rng;
+    ///
+    /// fn main() {
+    ///     let mut rng: rand::XorShiftRng = rand::SeedableRng::from_seed(&[1, 2, 3, 4]);
+    ///     println!("{}", rng.gen::<f64>());
+    ///     rng.reseed([5, 6, 7, 8]);
+    ///     println!("{}", rng.gen::<f64>());
+    /// }
+    /// ```
+    fn reseed(&mut self, Seed);
+
+    /// Create a new RNG with the given seed.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use std::rand;
+    /// use std::rand::Rng;
+    ///
+    /// fn main() {
+    ///     let mut rng: rand::XorShiftRng = rand::SeedableRng::from_seed(&[1, 2, 3, 4]);
+    ///     println!("{}", rng.gen::<f64>());
+    /// }
+    /// ```
+    fn from_seed(seed: Seed) -> Self;
+}
+
 /// Create a random number generator with a default algorithm and seed.
 ///
 /// It returns the cryptographically-safest `Rng` algorithm currently
@@ -686,6 +722,18 @@ impl Rng for StdRng {
     }
 }
 
+impl<'self> SeedableRng<&'self [uint]> for StdRng {
+    fn reseed(&mut self, seed: &'self [uint]) {
+        // the internal RNG can just be seeded from the above
+        // randomness.
+        self.rng.reseed(unsafe {cast::transmute(seed)})
+    }
+
+    fn from_seed(seed: &'self [uint]) -> StdRng {
+        StdRng { rng: SeedableRng::from_seed(unsafe {cast::transmute(seed)}) }
+    }
+}
+
 /// Create a weak random number generator with a default algorithm and seed.
 ///
 /// It returns the fastest `Rng` algorithm currently available in Rust without
@@ -723,11 +771,35 @@ impl Rng for XorShiftRng {
     }
 }
 
+impl SeedableRng<[u32, .. 4]> for XorShiftRng {
+    /// Reseed an XorShiftRng. This will fail if `seed` is entirely 0.
+    fn reseed(&mut self, seed: [u32, .. 4]) {
+        assert!(!seed.iter().all(|&x| x == 0),
+                "XorShiftRng.reseed called with an all zero seed.");
+
+        self.x = seed[0];
+        self.y = seed[1];
+        self.z = seed[2];
+        self.w = seed[3];
+    }
+
+    /// Create a new XorShiftRng. This will fail if `seed` is entirely 0.
+    fn from_seed(seed: [u32, .. 4]) -> XorShiftRng {
+        assert!(!seed.iter().all(|&x| x == 0),
+                "XorShiftRng::from_seed called with an all zero seed.");
+
+        XorShiftRng {
+            x: seed[0],
+            y: seed[1],
+            z: seed[2],
+            w: seed[3]
+        }
+    }
+}
+
 impl XorShiftRng {
     /// Create an xor shift random number generator with a random seed.
     pub fn new() -> XorShiftRng {
-        #[fixed_stack_segment]; #[inline(never)];
-
         // generate seeds the same way as seed(), except we have a
         // specific size, so we can just use a fixed buffer.
         let mut s = [0u8, ..16];
@@ -740,29 +812,21 @@ impl XorShiftRng {
             }
         }
         let s: &[u32, ..4] = unsafe { cast::transmute(&s) };
-        XorShiftRng::new_seeded(s[0], s[1], s[2], s[3])
-    }
-
-    /**
-     * Create a random number generator using the specified seed. A generator
-     * constructed with a given seed will generate the same sequence of values
-     * as all other generators constructed with the same seed.
-     */
-    pub fn new_seeded(x: u32, y: u32, z: u32, w: u32) -> XorShiftRng {
-        XorShiftRng {
-            x: x,
-            y: y,
-            z: z,
-            w: w,
-        }
+        SeedableRng::from_seed(*s)
     }
 }
 
-/// Create a new random seed of length `n`.
-pub fn seed(n: uint) -> ~[u8] {
-    let mut s = vec::from_elem(n as uint, 0_u8);
+/// Create a new random seed of length `n`. This should only be used
+/// to create types for which *any* bit pattern is valid.
+pub unsafe fn seed<T: Clone>(n: uint) -> ~[T] {
+    use unstable::intrinsics;
+    let mut s = vec::from_elem(n, intrinsics::init());
     let mut r = OSRng::new();
-    r.fill_bytes(s);
+
+    {
+        let s_u8 = cast::transmute::<&mut [T], &mut [u8]>(s);
+        r.fill_bytes(s_u8);
+    }
     s
 }
 
diff --git a/src/libstd/rand/reseeding.rs b/src/libstd/rand/reseeding.rs
index d471a5e4e10..727efff0101 100644
--- a/src/libstd/rand/reseeding.rs
+++ b/src/libstd/rand/reseeding.rs
@@ -97,6 +97,8 @@ mod test {
     use super::*;
     use rand::Rng;
     use default::Default;
+    use iter::range;
+    use option::{None, Some};
 
     struct Counter {
         i: u32
@@ -117,7 +119,7 @@ mod test {
 
     #[test]
     fn test_reseeding() {
-        let mut rs = ReseedingRng::from_options(Counter {i:0}, 100, ReseedWithDefault);
+        let mut rs = ReseedingRng::new(Counter {i:0}, 400, ReseedWithDefault);
 
         let mut i = 0;
         for _ in range(0, 1000) {
diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs
index 004dab8d73a..c1ca484754d 100644
--- a/src/libstd/rt/sched.rs
+++ b/src/libstd/rt/sched.rs
@@ -26,7 +26,7 @@ use rt::local::Local;
 use rt::rtio::{RemoteCallback, PausibleIdleCallback};
 use borrow::{to_uint};
 use cell::Cell;
-use rand::{XorShiftRng, Rng, Rand};
+use rand::{SeedableRng, XorShiftRng, Rng, Rand};
 use iter::range;
 use vec::{OwnedVector};
 
@@ -895,7 +895,7 @@ fn new_sched_rng() -> XorShiftRng {
     // know that the only way that we can fail here is `abort`ing?
     unsafe {libc::fclose(file);}
 
-    XorShiftRng::new_seeded(seeds[0], seeds[1], seeds[2], seeds[3])
+    SeedableRng::from_seed(seeds)
 }
 
 #[cfg(test)]
diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs
index bec11ff3a7d..2d209e40e42 100644
--- a/src/test/bench/core-map.rs
+++ b/src/test/bench/core-map.rs
@@ -15,7 +15,7 @@ use extra::treemap::TreeMap;
 use std::hashmap::{HashMap, HashSet};
 use std::io;
 use std::os;
-use std::rand::Rng;
+use std::rand::{Rng, IsaacRng, SeedableRng};
 use std::trie::TrieMap;
 use std::uint;
 use std::vec;
@@ -106,7 +106,7 @@ fn main() {
     let mut rand = vec::with_capacity(n_keys);
 
     {
-        let mut rng = std::rand::IsaacRng::new_seeded([1, 1, 1, 1, 1, 1, 1]);
+        let mut rng: IsaacRng = SeedableRng::from_seed(&[1, 1, 1, 1, 1, 1, 1]);
         let mut set = HashSet::new();
         while set.len() != n_keys {
             let next = rng.gen();
diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs
index 36ebdc54922..b9a8e74668f 100644
--- a/src/test/bench/core-set.rs
+++ b/src/test/bench/core-set.rs
@@ -163,11 +163,11 @@ fn main() {
         }
     };
 
-    let seed = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+    let seed = &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
     let max = 200000;
 
     {
-        let mut rng = rand::IsaacRng::new_seeded(seed);
+        let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed);
         let mut results = empty_results();
         results.bench_int(&mut rng, num_keys, max, || {
             let s: HashSet<uint> = HashSet::new();
@@ -181,7 +181,7 @@ fn main() {
     }
 
     {
-        let mut rng = rand::IsaacRng::new_seeded(seed);
+        let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed);
         let mut results = empty_results();
         results.bench_int(&mut rng, num_keys, max, || {
             let s: TreeSet<uint> = TreeSet::new();
@@ -195,7 +195,7 @@ fn main() {
     }
 
     {
-        let mut rng = rand::IsaacRng::new_seeded(seed);
+        let mut rng: rand::IsaacRng = rand::SeedableRng::from_seed(seed);
         let mut results = empty_results();
         results.bench_int(&mut rng, num_keys, max, || BitvSet::new());
         write_results("extra::bitv::BitvSet", &results);