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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.56  
changed lines
  Added in v.71

dashley@gmail.com
ViewVC Help
Powered by ViewVC 1.1.25