rcx

miscellaneous C library
git clone git://git.rr3.xyz/rcx
Log | Files | Refs | README | LICENSE

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 }