/[dtapublic]/projs/trunk/shared_source/c_datd/esrg_rand_int.c
ViewVC logotype

Contents of /projs/trunk/shared_source/c_datd/esrg_rand_int.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 71 - (show annotations) (download)
Sat Nov 5 11:07:06 2016 UTC (8 years, 1 month ago) by dashley
File MIME type: text/plain
File size: 6390 byte(s)
Set EOL properties appropriately to facilitate simultaneous Linux and Windows development.
1 //$Header$
2 //-------------------------------------------------------------------------------------------------
3 //This file is part of "David T. Ashley's Shared Source Code", a set of shared components
4 //integrated into many of David T. Ashley's projects.
5 //-------------------------------------------------------------------------------------------------
6 //This source code and any program in which it is compiled/used is provided under the MIT License,
7 //reproduced below.
8 //-------------------------------------------------------------------------------------------------
9 //Permission is hereby granted, free of charge, to any person obtaining a copy of
10 //this software and associated documentation files(the "Software"), to deal in the
11 //Software without restriction, including without limitation the rights to use,
12 //copy, modify, merge, publish, distribute, sublicense, and / or sell copies of the
13 //Software, and to permit persons to whom the Software is furnished to do so,
14 //subject to the following conditions :
15 //
16 //The above copyright notice and this permission notice shall be included in all
17 //copies or substantial portions of the Software.
18 //
19 //THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 //IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 //FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
22 //AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 //LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 //OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 //SOFTWARE.
26 //-------------------------------------------------------------------------------------------------
27 #define MODULE_ESRG_RAND_INT
28
29 #include <assert.h>
30 #include <string.h>
31 #include <time.h>
32
33 #include "esrg_rand_int.h"
34 #include "intfunc.h"
35
36
37 void ESRG_RAND_INT_Alg01_Init(struct ESRG_RAND_INT_Alg01RngState *state,
38 int init_val)
39 {
40 int i;
41
42 assert(state != NULL);
43 assert((init_val==-1) || (init_val>0));
44
45 //Regardless of init type, zero out the structure. Among other things,
46 //this sets the number of remaining random bits to zero.
47 memset(state, 0, sizeof(*state));
48
49 if (init_val == -1)
50 {
51 //This is the system randomness initialization case. Some value
52 //of system time should be adequate to start with.
53 state->rn_seed_whole = time(NULL);
54 state->rn_seed_fractional = time(NULL);
55
56 //Flip a few bits in the seeds to hopefully make them different
57 //(but it doesn't matter if they aren't).
58 state->rn_seed_whole ^= 0xA5A5A5A5;
59 state->rn_seed_fractional ^= 0x5A5A5A5A;
60
61 //Be absolutely sure that the seeds can't be zero.
62 state->rn_seed_whole |= 0x1;
63 state->rn_seed_fractional |= 0x2;
64
65 //Iterate a small number of times to add further randomness
66 //to the two seeds.
67 for (i=0; i<3; i++)
68 {
69 state->rn_seed_whole
70 = INTFUNC_rn_power_res_16807_mapping(state->rn_seed_whole);
71 }
72
73 for (i=0; i<7; i++)
74 {
75 state->rn_seed_fractional
76 = INTFUNC_rn_power_res_16807_mapping(state->rn_seed_fractional);
77 }
78 }
79 else
80 {
81 //This is the branch where the random seed is supplied. We can
82 //use very much the same approach as above to try to get something
83 //random.
84 state->rn_seed_whole = init_val;
85 state->rn_seed_fractional = init_val;
86
87 //Flip a few bits in the seeds to hopefully make them different
88 //(but it doesn't matter if they aren't).
89 state->rn_seed_whole ^= 0xA5A5A5A5;
90 state->rn_seed_fractional ^= 0x5A5A5A5A;
91
92 //Be absolutely sure that the seeds can't be zero.
93 state->rn_seed_whole |= 0x1;
94 state->rn_seed_fractional |= 0x2;
95
96 //Iterate a small number of times to add further randomness
97 //to the two seeds.
98 for (i=0; i<3; i++)
99 {
100 state->rn_seed_whole
101 = INTFUNC_rn_power_res_16807_mapping(state->rn_seed_whole);
102 }
103
104 for (i=0; i<7; i++)
105 {
106 state->rn_seed_fractional
107 = INTFUNC_rn_power_res_16807_mapping(state->rn_seed_fractional);
108 }
109 }
110
111 //At this point the state is randomized. The number of bits valid
112 //in the bit reservoir is set to zero, so will force a restock
113 //next time.
114 }
115
116
117 //Restocks the bit reservoir.
118 static void ESRG_RAND_INT_Alg01_RestockBitBuffer(
119 struct ESRG_RAND_INT_Alg01RngState *state
120 )
121 {
122 assert(state != NULL);
123
124 //We need to keep chugging along until we get an integer with the top two
125 //bits clear. This is the only way to get a random distribution of bits.
126 do
127 {
128 assert(state->rn_seed_fractional != 0);
129 state->rn_seed_fractional
130 = INTFUNC_rn_power_res_16807_mapping(state->rn_seed_fractional);
131 } while (state->rn_seed_fractional & 0xC0000000);
132
133 //At this point the lower 30 bits should be random.
134 state->bit_buffer = state->rn_seed_fractional;
135 state->n_bb_valid = 30;
136 }
137
138
139 unsigned int ESRG_RAND_INT_Alg01_RandomBit(
140 struct ESRG_RAND_INT_Alg01RngState *state
141 )
142 {
143 int rv;
144
145 assert(state != NULL);
146
147 //Restock the supply of bits if necessary.
148 if (state->n_bb_valid == 0)
149 ESRG_RAND_INT_Alg01_RestockBitBuffer(state);
150
151 if (state->bit_buffer & 0x01)
152 rv = 1;
153 else
154 rv = 0;
155
156 state->bit_buffer >>= 1;
157 state->n_bb_valid--;
158
159 return(rv);
160 }
161
162
163 unsigned int ESRG_RAND_INT_Alg01_RandomByte(
164 struct ESRG_RAND_INT_Alg01RngState *state
165 )
166 {
167 int rv;
168
169 assert(state != NULL);
170
171 //Be sure enough bits to yank a byte.
172 if (state->n_bb_valid < 8)
173 ESRG_RAND_INT_Alg01_RestockBitBuffer(state);
174
175 //Grab the byte and return.
176 rv = state->bit_buffer & 0xFF;
177 state->bit_buffer >>= 8; //Must roll down to get new set of bits.
178 state->n_bb_valid -= 8;
179
180 return(rv);
181 }
182
183
184 const char *ESRG_RAND_INT_cvcinfo(void)
185 {
186 return("$Header$");
187 }
188
189
190 const char *ESRG_RAND_INT_hvcinfo(void)
191 {
192 return(ESRG_RAND_INT_H_VERSION);
193 }
194
195 //End of esrg_rand_int.c.

Properties

Name Value
svn:eol-style native
svn:keywords Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25