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