rand.h (1577B)
1 #pragma once 2 3 #include "bits.h" 4 #include "def.h" 5 6 /* The default seed used by r_rand when no argument is provided. To change the 7 * seed, assign it directly (e.g., using r_trand). */ 8 extern u64 r_seed; 9 10 /* The default key used by r_hash when no key argument is provided. To change 11 * the key, use r_make_hash_key. */ 12 extern u64 r_hash_key[4]; 13 14 static inline u64 15 r_wymix_(u64 x, u64 y) { 16 u64 h, l; 17 r_mulu64(&h, &l, x, y); 18 return h ^ l; 19 } 20 21 /* Hash the given data using the wyhash algorithm. */ 22 #define r_hash(data, len, seed, ...) \ 23 r_hash_((data), (len), (seed), VA_DEFAULT(,##__VA_ARGS__, &r_hash_key)) 24 u64 r_hash_(void *data, u64 len, u64 seed, u64 (*key)[4]); 25 26 void r_make_hash_key(u64 (*key)[4], u64 seed); 27 28 /* Generate len (truly) random bytes using the /dev/urandom interface and put 29 * the result in buf. Return 0 on success; on error, return -1 and set errno. 30 * r_trand is slow; it's intented use is to seed userspace PRNG's (like 31 * r_prand64) on program initialization. 32 * TODO: Use getrandom instead? getrandom blocks when /dev/urandom doesn't have 33 * enough entropy yet. */ 34 int r_trand(void *buf, usize len); 35 36 /* Generate a pseudo-random u64 seeded from the given u64*, or from r_seed if 37 * no argument is provided. Without an argument, r_prand is not thread-safe. 38 * The PRNG algorithm (wyrand) is fast but not safe for cryptographic use. */ 39 #define r_prand64(...) r_prand64_(VA_DEFAULT(,##__VA_ARGS__, &r_seed)) 40 static inline u64 41 r_prand64_(u64 *seed) { 42 *seed += U64_C(0xa0761d6478bd642f); 43 return r_wymix_(*seed, *seed ^ U64_C(0xe7037ed1a0b428db)); 44 }