rng.rs 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. use std::sync::Mutex;
  2. use crate::time;
  3. static RNG: Mutex<XorShift64> = Mutex::new(XorShift64::default());
  4. pub fn shuffle_rng() {
  5. let mut rng = RNG.lock().expect("RNG mutex is poisoned.");
  6. rng.inject_time();
  7. }
  8. pub fn random_numeric_string(length: usize) -> String {
  9. let mut out = String::new();
  10. while out.len() < length {
  11. let num = random_number();
  12. out.push_str(&num.to_string());
  13. }
  14. out[..length].to_string()
  15. }
  16. pub fn random_number() -> u64 {
  17. let mut rng = RNG.lock().expect("RNG mutex is poisoned.");
  18. rng.inject_time();
  19. rng.next()
  20. }
  21. struct XorShift64 {
  22. state: u64,
  23. }
  24. impl XorShift64 {
  25. const fn new(seed: u64) -> Self {
  26. Self { state: seed }
  27. }
  28. const fn default() -> Self {
  29. Self::new(49)
  30. }
  31. fn inject_time(&mut self) {
  32. self.state ^= time::time_millis() as u64 % 1000;
  33. }
  34. fn next(&mut self) -> u64 {
  35. self.state ^= self.state << 13;
  36. self.state ^= self.state >> 7;
  37. self.state ^= self.state << 17;
  38. self.state
  39. }
  40. }
  41. impl Default for XorShift64 {
  42. fn default() -> Self {
  43. Self::default()
  44. }
  45. }