Back to index

lightning-sunbird  0.9+nobinonly
random.c
Go to the documentation of this file.
00001 /*
00002 ** 2001 September 15
00003 **
00004 ** The author disclaims copyright to this source code.  In place of
00005 ** a legal notice, here is a blessing:
00006 **
00007 **    May you do good and not evil.
00008 **    May you find forgiveness for yourself and forgive others.
00009 **    May you share freely, never taking more than you give.
00010 **
00011 *************************************************************************
00012 ** This file contains code to implement a pseudo-random number
00013 ** generator (PRNG) for SQLite.
00014 **
00015 ** Random numbers are used by some of the database backends in order
00016 ** to generate random integer keys for tables or random filenames.
00017 **
00018 ** $Id: random.c,v 1.15 2006/01/06 14:32:20 drh Exp $
00019 */
00020 #include "sqliteInt.h"
00021 #include "os.h"
00022 
00023 
00024 /*
00025 ** Get a single 8-bit random value from the RC4 PRNG.  The Mutex
00026 ** must be held while executing this routine.
00027 **
00028 ** Why not just use a library random generator like lrand48() for this?
00029 ** Because the OP_NewRowid opcode in the VDBE depends on having a very
00030 ** good source of random numbers.  The lrand48() library function may
00031 ** well be good enough.  But maybe not.  Or maybe lrand48() has some
00032 ** subtle problems on some systems that could cause problems.  It is hard
00033 ** to know.  To minimize the risk of problems due to bad lrand48()
00034 ** implementations, SQLite uses this random number generator based
00035 ** on RC4, which we know works very well.
00036 **
00037 ** (Later):  Actually, OP_NewRowid does not depend on a good source of
00038 ** randomness any more.  But we will leave this code in all the same.
00039 */
00040 static int randomByte(){
00041   unsigned char t;
00042 
00043   /* All threads share a single random number generator.
00044   ** This structure is the current state of the generator.
00045   */
00046   static struct {
00047     unsigned char isInit;          /* True if initialized */
00048     unsigned char i, j;            /* State variables */
00049     unsigned char s[256];          /* State variables */
00050   } prng;
00051 
00052   /* Initialize the state of the random number generator once,
00053   ** the first time this routine is called.  The seed value does
00054   ** not need to contain a lot of randomness since we are not
00055   ** trying to do secure encryption or anything like that...
00056   **
00057   ** Nothing in this file or anywhere else in SQLite does any kind of
00058   ** encryption.  The RC4 algorithm is being used as a PRNG (pseudo-random
00059   ** number generator) not as an encryption device.
00060   */
00061   if( !prng.isInit ){
00062     int i;
00063     char k[256];
00064     prng.j = 0;
00065     prng.i = 0;
00066     sqlite3OsRandomSeed(k);
00067     for(i=0; i<256; i++){
00068       prng.s[i] = i;
00069     }
00070     for(i=0; i<256; i++){
00071       prng.j += prng.s[i] + k[i];
00072       t = prng.s[prng.j];
00073       prng.s[prng.j] = prng.s[i];
00074       prng.s[i] = t;
00075     }
00076     prng.isInit = 1;
00077   }
00078 
00079   /* Generate and return single random byte
00080   */
00081   prng.i++;
00082   t = prng.s[prng.i];
00083   prng.j += t;
00084   prng.s[prng.i] = prng.s[prng.j];
00085   prng.s[prng.j] = t;
00086   t += prng.s[prng.i];
00087   return prng.s[t];
00088 }
00089 
00090 /*
00091 ** Return N random bytes.
00092 */
00093 void sqlite3Randomness(int N, void *pBuf){
00094   unsigned char *zBuf = pBuf;
00095   sqlite3OsEnterMutex();
00096   while( N-- ){
00097     *(zBuf++) = randomByte();
00098   }
00099   sqlite3OsLeaveMutex();
00100 }