1 | /* Copyright (C) 2007 MySQL AB & Michael Widenius |
2 | |
3 | This program is free software; you can redistribute it and/or modify |
4 | it under the terms of the GNU General Public License as published by |
5 | the Free Software Foundation; version 2 of the License. |
6 | |
7 | This program is distributed in the hope that it will be useful, |
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | GNU General Public License for more details. |
11 | |
12 | You should have received a copy of the GNU General Public License |
13 | along with this program; if not, write to the Free Software |
14 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA */ |
15 | |
16 | #include "mysys_priv.h" |
17 | #include <my_rnd.h> |
18 | #include <m_string.h> |
19 | |
20 | /* |
21 | Initialize random generator |
22 | |
23 | NOTES |
24 | MySQL's password checks depends on this, so don't do any changes |
25 | that changes the random numbers that are generated! |
26 | */ |
27 | |
28 | void my_rnd_init(struct my_rnd_struct *rand_st, ulong seed1, ulong seed2) |
29 | { |
30 | #ifdef HAVE_valgrind |
31 | bzero((char*) rand_st,sizeof(*rand_st)); /* Avoid UMC varnings */ |
32 | #endif |
33 | rand_st->max_value= 0x3FFFFFFFL; |
34 | rand_st->max_value_dbl=(double) rand_st->max_value; |
35 | rand_st->seed1=seed1%rand_st->max_value ; |
36 | rand_st->seed2=seed2%rand_st->max_value; |
37 | } |
38 | |
39 | |
40 | /* |
41 | Generate random number. |
42 | |
43 | SYNOPSIS |
44 | my_rnd() |
45 | rand_st INOUT Structure used for number generation |
46 | |
47 | RETURN VALUE |
48 | generated pseudo random number |
49 | |
50 | NOTE: |
51 | This is codes so that it can be called by two threads at the same time |
52 | with minimum impact. |
53 | (As the number is supposed to be random, it doesn't matter much if |
54 | rand->seed1 or rand->seed2 are updated with slightly wrong numbers or |
55 | if two threads gets the same number. |
56 | */ |
57 | |
58 | double my_rnd(struct my_rnd_struct *rand_st) |
59 | { |
60 | unsigned long seed1; |
61 | seed1= (rand_st->seed1*3+rand_st->seed2) % rand_st->max_value; |
62 | rand_st->seed2=(seed1+rand_st->seed2+33) % rand_st->max_value; |
63 | rand_st->seed1= seed1; |
64 | return (((double) seed1)/rand_st->max_value_dbl); |
65 | } |
66 | |
67 | |
68 | /** |
69 | Generate a random number using the OpenSSL/yaSSL supplied |
70 | random number generator if available. |
71 | |
72 | @param rand_st [INOUT] Structure used for number generation |
73 | only if none of the SSL libraries are |
74 | available. |
75 | |
76 | @retval Generated random number. |
77 | */ |
78 | |
79 | double my_rnd_ssl(struct my_rnd_struct *rand_st) |
80 | { |
81 | |
82 | #if defined(HAVE_YASSL) || defined(HAVE_OPENSSL) |
83 | int rc; |
84 | unsigned int res; |
85 | |
86 | #if defined(HAVE_YASSL) |
87 | rc= yaSSL::RAND_bytes((unsigned char *) &res, sizeof (unsigned int)); |
88 | #else |
89 | rc= RAND_bytes((unsigned char *) &res, sizeof (unsigned int)); |
90 | #endif /* HAVE_YASSL */ |
91 | |
92 | if (rc) |
93 | return (double)res / (double)UINT_MAX; |
94 | #endif /* defined(HAVE_YASSL) || defined(HAVE_OPENSSL) */ |
95 | |
96 | return my_rnd(rand_st); |
97 | } |
98 | |