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
28void 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
58double 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
79double 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