File Coverage

random.c
Criterion Covered Total %
statement 27 27 100.0
branch 8 8 100.0
condition n/a
subroutine n/a
pod n/a
total 35 35 100.0


line stmt bran cond sub pod time code
1             /*
2             ** 2001 September 15
3             **
4             ** The author disclaims copyright to this source code. In place of
5             ** a legal notice, here is a blessing:
6             **
7             ** May you do good and not evil.
8             ** May you find forgiveness for yourself and forgive others.
9             ** May you share freely, never taking more than you give.
10             **
11             *************************************************************************
12             ** This file contains code to implement a pseudo-random number
13             ** generator (PRNG) for SQLite.
14             **
15             ** Random numbers are used by some of the database backends in order
16             ** to generate random integer keys for tables or random filenames.
17             **
18             ** $Id: random.c,v 1.1.1.1 2004/08/08 15:03:58 matt Exp $
19             */
20             #include "sqliteInt.h"
21             #include "os.h"
22              
23              
24             /*
25             ** Get a single 8-bit random value from the RC4 PRNG. The Mutex
26             ** must be held while executing this routine.
27             **
28             ** Why not just use a library random generator like lrand48() for this?
29             ** Because the OP_NewRecno opcode in the VDBE depends on having a very
30             ** good source of random numbers. The lrand48() library function may
31             ** well be good enough. But maybe not. Or maybe lrand48() has some
32             ** subtle problems on some systems that could cause problems. It is hard
33             ** to know. To minimize the risk of problems due to bad lrand48()
34             ** implementations, SQLite uses this random number generator based
35             ** on RC4, which we know works very well.
36             */
37 844           static int randomByte(){
38             unsigned char t;
39              
40             /* All threads share a single random number generator.
41             ** This structure is the current state of the generator.
42             */
43             static struct {
44             unsigned char isInit; /* True if initialized */
45             unsigned char i, j; /* State variables */
46             unsigned char s[256]; /* State variables */
47             } prng;
48              
49             /* Initialize the state of the random number generator once,
50             ** the first time this routine is called. The seed value does
51             ** not need to contain a lot of randomness since we are not
52             ** trying to do secure encryption or anything like that...
53             **
54             ** Nothing in this file or anywhere else in SQLite does any kind of
55             ** encryption. The RC4 algorithm is being used as a PRNG (pseudo-random
56             ** number generator) not as an encryption device.
57             */
58 844 100         if( !prng.isInit ){
59             int i;
60             char k[256];
61 21           prng.j = 0;
62 21           prng.i = 0;
63 21           sqliteOsRandomSeed(k);
64 5397 100         for(i=0; i<256; i++){
65 5376           prng.s[i] = i;
66             }
67 5397 100         for(i=0; i<256; i++){
68 5376           prng.j += prng.s[i] + k[i];
69 5376           t = prng.s[prng.j];
70 5376           prng.s[prng.j] = prng.s[i];
71 5376           prng.s[i] = t;
72             }
73 21           prng.isInit = 1;
74             }
75              
76             /* Generate and return single random byte
77             */
78 844           prng.i++;
79 844           t = prng.s[prng.i];
80 844           prng.j += t;
81 844           prng.s[prng.i] = prng.s[prng.j];
82 844           prng.s[prng.j] = t;
83 844           t += prng.s[prng.i];
84 844           return prng.s[t];
85             }
86              
87             /*
88             ** Return N random bytes.
89             */
90 158           void sqliteRandomness(int N, void *pBuf){
91 158           unsigned char *zBuf = pBuf;
92 158           sqliteOsEnterMutex();
93 1002 100         while( N-- ){
94 844           *(zBuf++) = randomByte();
95             }
96 158           sqliteOsLeaveMutex();
97 158           }