use num_integer::Integer; use num_traits::{ToPrimitive, Zero};
/// A trait for sampling random big integers. /// /// The `rand` feature must be enabled to use this. See crate-level documentation for details. pubtrait RandBigInt { /// Generate a random [`BigUint`] of the given bit size. fn gen_biguint(&mutself, bit_size: u64) -> BigUint;
/// Generate a random [ BigInt`] of the given bit size. fn gen_bigint(&mutself, bit_size: u64) -> BigInt;
/// Generate a random [`BigUint`] less than the given bound. Fails /// when the bound is zero. fn gen_biguint_below(&mutself, bound: &BigUint) -> BigUint;
/// Generate a random [`BigUint`] within the given range. The lower /// bound is inclusive; the upper bound is exclusive. Fails when /// the upper bound is not greater than the lower bound. fn gen_biguint_range(&mutself, lbound: &BigUint, ubound: &BigUint) -> BigUint;
/// Generate a random [`BigInt`] within the given range. The lower /// bound is inclusive; the upper bound is exclusive. Fails when /// the upper bound is not greater than the lower bound. fn gen_bigint_range(&mutself, lbound: &BigInt, ubound: &BigInt) -> BigInt;
}
fn gen_bits<R: Rng + ?Sized>(rng: &mut R, data: &mut [u32], rem: u64) { // `fill` is faster than many `gen::<u32>` calls
rng.fill(data); if rem > 0 { let last = data.len() - 1;
data[last] >>= 32 - rem;
}
}
impl<R: Rng + ?Sized> RandBigInt for R {
cfg_digit!( fn gen_biguint(&mutself, bit_size: u64) -> BigUint { let (digits, rem) = bit_size.div_rem(&32); let len = (digits + (rem > 0) as u64)
.to_usize()
.expect("capacity overflow"); letmut data = vec![0u32; len];
gen_bits(self, &mut data, rem);
biguint_from_vec(data)
}
fn gen_biguint(&mutself, bit_size: u64) -> BigUint { use core::slice;
let (digits, rem) = bit_size.div_rem(&32); let len = (digits + (rem > 0) as u64)
.to_usize()
.expect("capacity overflow"); let native_digits = Integer::div_ceil(&bit_size, &64); let native_len = native_digits.to_usize().expect("capacity overflow"); letmut data = vec![0u64; native_len]; unsafe { // Generate bits in a `&mut [u32]` slice for value stability let ptr = data.as_mut_ptr() as *mut u32;
debug_assert!(native_len * 2 >= len); let data = slice::from_raw_parts_mut(ptr, len);
gen_bits(self, data, rem);
} #[cfg(target_endian = "big")] for digit in &mut data { // swap u32 digits into u64 endianness
*digit = (*digit << 32) | (*digit >> 32);
}
biguint_from_vec(data)
}
);
fn gen_bigint(&mutself, bit_size: u64) -> BigInt { loop { // Generate a random BigUint... let biguint = self.gen_biguint(bit_size); // ...and then randomly assign it a Sign... let sign = if biguint.is_zero() { // ...except that if the BigUint is zero, we need to try // again with probability 0.5. This is because otherwise, // the probability of generating a zero BigInt would be // double that of any other number. ifself.gen() { continue;
} else {
NoSign
}
} elseifself.gen() {
Plus
} else {
Minus
}; return BigInt::from_biguint(sign, biguint);
}
}
fn gen_biguint_below(&mutself, bound: &BigUint) -> BigUint {
assert!(!bound.is_zero()); let bits = bound.bits(); loop { let n = self.gen_biguint(bits); if n < *bound { return n;
}
}
}
impl SampleUniform for BigInt { type Sampler = UniformBigInt;
}
/// A random distribution for [`BigUint`] and [`BigInt`] values of a particular bit size. /// /// The `rand` feature must be enabled to use this. See crate-level documentation for details. #[derive(Clone, Copy, Debug)] pubstruct RandomBits {
bits: u64,
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.