1 /* -*- Mode: c; c-basic-offset: 2 -*-
2  *
3  * seed.c - Seeding functions
4  *
5  * This is free and unencumbered software released into the public domain.
6  *
7  * Anyone is free to copy, modify, publish, use, compile, sell, or
8  * distribute this software, either in source code form or as a compiled
9  * binary, for any purpose, commercial or non-commercial, and by any
10  * means.
11  *
12  * In jurisdictions that recognize copyright laws, the author or authors
13  * of this software dedicate any and all copyright interest in the
14  * software to the public domain. We make this dedication for the benefit
15  * of the public at large and to the detriment of our heirs and
16  * successors. We intend this dedication to be an overt act of
17  * relinquishment in perpetuity of all present and future rights to this
18  * software under copyright law.
19  *
20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26  * OTHER DEALINGS IN THE SOFTWARE.
27  *
28  * For more information, please refer to <http://unlicense.org/>
29  *
30  */
31 
32 #ifdef MTWIST_CONFIG
33 #include <mtwist_config.h>
34 #endif
35 
36 #include <stdio.h>
37 
38 #ifdef HAVE_TIME_H
39 #include <time.h>
40 #endif
41 
42 #ifdef HAVE_UNISTD_H
43 #include <unistd.h>
44 #endif
45 
46 #ifdef HAVE_STDINT_H
47 #include <stdint.h>
48 #else
49 /* pessimistic - use an unsigned long */
50 typedef unsigned long uint32_t;
51 #endif
52 
53 #include <mtwist.h>
54 
55 #include <mtwist_internal.h>
56 
57 
58 /**
59  * mtwist_seed_from_system:
60  * @mt: mt object
61  *
62  * Get a 32 bit unsigned integer random seed based on system sources
63  *
64  * Return value: seed with only lower 32 bits valid
65  */
66 unsigned long
mtwist_seed_from_system(mtwist * mt)67 mtwist_seed_from_system(mtwist* mt)
68 {
69   /* SOURCE 1: processor clock ticks since process started */
70   uint32_t a = (uint32_t)clock();
71   /* SOURCE 2: unix time in seconds since epoch */
72   uint32_t b = (uint32_t)time(NULL);
73   uint32_t c;
74 #ifdef HAVE_UNISTD_H
75   /* SOURCE 3: process ID (on unix) */
76   c = getpid();
77 #else
78   c = 0;
79 #endif
80 
81   /* Mix seed sources using public domain code from
82    * http://www.burtleburtle.net/bob/c/lookup3.c
83    */
84 
85 #define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k))))
86 
87   /* inlined mix(a, b, c) macro */
88   a -= c;  a ^= rot(c, 4);  c += b;
89   b -= a;  b ^= rot(a, 6);  a += c;
90   c -= b;  c ^= rot(b, 8);  b += a;
91   a -= c;  a ^= rot(c,16);  c += b;
92   b -= a;  b ^= rot(a,19);  /* a += c; */ /* CLANG: not needed because of below */
93   c -= b;  c ^= rot(b, 4);  /* b += a; */ /* CLANG: last calculation not needed */
94 
95   if(mt->static_system_seed)
96     c = MT_STATIC_SEED;
97 
98   return (unsigned long)c;
99 }
100