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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 56 - (hide annotations) (download)
Sat Oct 29 01:53:01 2016 UTC (7 years, 8 months ago) by dashley
File MIME type: text/plain
File size: 6585 byte(s)
License and property (keyword) changes.
1 dashley 56 //$Header$
2 dashley 25 //-------------------------------------------------------------------------------------------------
3 dashley 56 //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 dashley 25 //-------------------------------------------------------------------------------------------------
6 dashley 56 //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 dashley 25 //
16 dashley 56 //The above copyright notice and this permission notice shall be included in all
17     //copies or substantial portions of the Software.
18 dashley 25 //
19 dashley 56 //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 dashley 25 //-------------------------------------------------------------------------------------------------
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 dashley 56 return("$Header$");
187 dashley 25 }
188    
189    
190     const char *ESRG_RAND_INT_hvcinfo(void)
191     {
192     return(ESRG_RAND_INT_H_VERSION);
193     }
194    
195 dashley 56 //End of esrg_rand_int.c.

Properties

Name Value
svn:keywords Header

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25