wasCSharpSQLite – Blame information for rev 3

Subversion Repositories:
Rev:
Rev Author Line No. Line
1 office 1 using System;
2 using System.Diagnostics;
3  
4 using i64 = System.Int64;
5 using u8 = System.Byte;
6 using u32 = System.UInt32;
7 using u64 = System.UInt64;
8  
9 namespace Community.CsharpSqlite
10 {
11 public partial class Sqlite3
12 {
13 /*
14 ** 2001 September 15
15 **
16 ** The author disclaims copyright to this source code. In place of
17 ** a legal notice, here is a blessing:
18 **
19 ** May you do good and not evil.
20 ** May you find forgiveness for yourself and forgive others.
21 ** May you share freely, never taking more than you give.
22 **
23 *************************************************************************
24 ** This file contains code to implement a pseudo-random number
25 ** generator (PRNG) for SQLite.
26 **
27 ** Random numbers are used by some of the database backends in order
28 ** to generate random integer keys for tables or random filenames.
29 *************************************************************************
30 ** Included in SQLite3 port to C#-SQLite; 2008 Noah B Hart
31 ** C#-SQLite is an independent reimplementation of the SQLite software library
32 **
33 ** SQLITE_SOURCE_ID: 2010-08-23 18:52:01 42537b60566f288167f1b5864a5435986838e3a3
34 **
35 *************************************************************************
36 */
37 //#include "sqliteInt.h"
38  
39  
40 /* All threads share a single random number generator.
41 ** This structure is the current state of the generator.
42 */
43 public class sqlite3PrngType
44 {
45 public bool isInit; /* True if initialized */
46 public int i;
47 public int j; /* State variables */
48 public u8[] s = new u8[256]; /* State variables */
49  
50 public sqlite3PrngType Copy()
51 {
52 sqlite3PrngType cp = (sqlite3PrngType)MemberwiseClone();
53 cp.s = new u8[s.Length];
54 Array.Copy( s, cp.s, s.Length );
55 return cp;
56 }
57 }
58 public static sqlite3PrngType sqlite3Prng = new sqlite3PrngType();
59 /*
60 ** Get a single 8-bit random value from the RC4 PRNG. The Mutex
61 ** must be held while executing this routine.
62 **
63 ** Why not just use a library random generator like lrand48() for this?
64 ** Because the OP_NewRowid opcode in the VDBE depends on having a very
65 ** good source of random numbers. The lrand48() library function may
66 ** well be good enough. But maybe not. Or maybe lrand48() has some
67 ** subtle problems on some systems that could cause problems. It is hard
68 ** to know. To minimize the risk of problems due to bad lrand48()
69 ** implementations, SQLite uses this random number generator based
70 ** on RC4, which we know works very well.
71 **
72 ** (Later): Actually, OP_NewRowid does not depend on a good source of
73 ** randomness any more. But we will leave this code in all the same.
74 */
75 static u8 randomu8()
76 {
77 u8 t;
78  
79 /* The "wsdPrng" macro will resolve to the pseudo-random number generator
80 ** state vector. If writable static data is unsupported on the target,
81 ** we have to locate the state vector at run-time. In the more common
82 ** case where writable static data is supported, wsdPrng can refer directly
83 ** to the "sqlite3Prng" state vector declared above.
84 */
85 #if SQLITE_OMIT_WSD
86 struct sqlite3PrngType *p = &GLOBAL(struct sqlite3PrngType, sqlite3Prng);
87 //# define wsdPrng p[0]
88 #else
89 //# define wsdPrng sqlite3Prng
90 sqlite3PrngType wsdPrng = sqlite3Prng;
91 #endif
92  
93  
94 /* Initialize the state of the random number generator once,
95 ** the first time this routine is called. The seed value does
96 ** not need to contain a lot of randomness since we are not
97 ** trying to do secure encryption or anything like that...
98 **
99 ** Nothing in this file or anywhere else in SQLite does any kind of
100 ** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random
101 ** number generator) not as an encryption device.
102 */
103 if ( !wsdPrng.isInit )
104 {
105 int i;
106 u8[] k = new u8[256];
107 wsdPrng.j = 0;
108 wsdPrng.i = 0;
109 sqlite3OsRandomness( sqlite3_vfs_find( string.Empty ), 256, k );
110 for ( i = 0; i < 255; i++ )
111 {
112 wsdPrng.s[i] = (u8)i;
113 }
114 for ( i = 0; i < 255; i++ )
115 {
116 wsdPrng.j = (u8)( wsdPrng.j + wsdPrng.s[i] + k[i] );
117 t = wsdPrng.s[wsdPrng.j];
118 wsdPrng.s[wsdPrng.j] = wsdPrng.s[i];
119 wsdPrng.s[i] = t;
120 }
121 wsdPrng.isInit = true;
122 }
123  
124 /* Generate and return single random u8
125 */
126 wsdPrng.i++;
127 t = wsdPrng.s[(u8)wsdPrng.i];
128 wsdPrng.j = (u8)( wsdPrng.j + t );
129 wsdPrng.s[(u8)wsdPrng.i] = wsdPrng.s[wsdPrng.j];
130 wsdPrng.s[wsdPrng.j] = t;
131 t += wsdPrng.s[(u8)wsdPrng.i];
132 return wsdPrng.s[t];
133 }
134  
135 /*
136 ** Return N random u8s.
137 */
138 static void sqlite3_randomness( int N, ref i64 pBuf )
139 {
140 ////u8[] zBuf = new u8[N];
141 pBuf = 0;
142 #if SQLITE_THREADSAFE
143 sqlite3_mutex mutex = sqlite3MutexAlloc( SQLITE_MUTEX_STATIC_PRNG );
144 #endif
145 sqlite3_mutex_enter( mutex );
146 while ( N-- > 0 )
147 {
148 pBuf = (u32)( ( pBuf << 8 ) + randomu8() );// zBuf[N] = randomu8();
149 }
150 sqlite3_mutex_leave( mutex );
151 }
152  
153 static void sqlite3_randomness( byte[] pBuf, int Offset, int N )
154 {
155 i64 iBuf = System.DateTime.Now.Ticks;
156 #if SQLITE_THREADSAFE
157 sqlite3_mutex mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
158 #endif
159 sqlite3_mutex_enter( mutex );
160 while ( N-- > 0 )
161 {
162 iBuf = (u32)( ( iBuf << 8 ) + randomu8() );// zBuf[N] = randomu8();
163 pBuf[Offset++] = (byte)iBuf;
164 }
165 sqlite3_mutex_leave( mutex );
166 }
167  
168 #if !SQLITE_OMIT_BUILTIN_TEST
169 /*
170 ** For testing purposes, we sometimes want to preserve the state of
171 ** PRNG and restore the PRNG to its saved state at a later time, or
172 ** to reset the PRNG to its initial state. These routines accomplish
173 ** those tasks.
174 **
175 ** The sqlite3_test_control() interface calls these routines to
176 ** control the PRNG.
177 */
178 static sqlite3PrngType sqlite3SavedPrng = null;
179 static void sqlite3PrngSaveState()
180 {
181 sqlite3SavedPrng = sqlite3Prng.Copy();
182 // memcpy(
183 // &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),
184 // &GLOBAL(struct sqlite3PrngType, sqlite3Prng),
185 // sizeof(sqlite3Prng)
186 //);
187 }
188 static void sqlite3PrngRestoreState()
189 {
190 sqlite3Prng = sqlite3SavedPrng.Copy();
191 //memcpy(
192 // &GLOBAL(struct sqlite3PrngType, sqlite3Prng),
193 // &GLOBAL(struct sqlite3PrngType, sqlite3SavedPrng),
194 // sizeof(sqlite3Prng)
195 //);
196 }
197 static void sqlite3PrngResetState()
198 {
199 sqlite3Prng.isInit = false;// GLOBAL(struct sqlite3PrngType, sqlite3Prng).isInit = 0;
200 }
201 #endif //* SQLITE_OMIT_BUILTIN_TEST */
202 }
203 }