summaryrefslogtreecommitdiffabout
path: root/pwmanager/pwmanager/randomizer.cpp
blob: e623f5132fd3f72d06f2ee1488e45ce188f4f012 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/***************************************************************************
 *                                                                         *
 *   copyright (C) 2003, 2004 by Michael Buesch                            *
 *   email: mbuesch@freenet.de                                             *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License version 2        *
 *   as published by the Free Software Foundation.                         *
 *                                                                         *
 ***************************************************************************/

/***************************************************************************
 * copyright (C) 2004 by Ulf Schenk
 * This file is originaly based on version 1.0.1 of pwmanager
 * and was modified to run on embedded devices that run microkde
 *
 * $Id$
 **************************************************************************/  

#include "randomizer.h"
#include "pwmexception.h"

#include <stdlib.h>
#include <time.h>


Randomizer * Randomizer::rndObj (0);

Randomizer::Randomizer()
{
	// probe for random devices
	rndDev = fopen("/dev/urandom", "r");
	if (rndDev)
		return;
	rndDev = fopen("/dev/random", "r");
	if (rndDev)
		return;
	// fall back to rand_r()
	seed = time(0);
}

Randomizer::~Randomizer()
{
	if (rndDev) {
		if (fclose(rndDev)) {
			printWarn("failed closing the random-device!");
		}
	}
}

char Randomizer::genRndChar()
{
	if (rndDev) {
		/* we have a rand-device-node */
		return (getc(rndDev));
	} else {
		/* we don't have a random-device-node.
		 * so fall back to rand_r()
		 */
		return (rand_r(&seed) % 0xFF);
	}
}

int Randomizer::genRndInt()
{
	if(rndDev) {
		int ret;
		if (sizeof(int) == 4) {
			(reinterpret_cast<char *>(&ret))[0] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[1] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[2] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[3] = getc(rndDev);
		} else if (sizeof(int) == 8) {
			(reinterpret_cast<char *>(&ret))[0] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[1] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[2] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[3] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[4] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[5] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[6] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[7] = getc(rndDev);
		} else {
			printWarn(string(__FILE__) + ":" + tostr(__LINE__)
				  + ":  sizeof(int) != 4 && sizeof(int) != 8");
			rndDev = 0;
			seed = time(0);
			return genRndInt();
		}
		return ret;
	} else {
		return rand_r(&seed);
	}
}

unsigned int Randomizer::genRndUInt()
{
	if(rndDev) {
		unsigned int ret;
		if (sizeof(unsigned int) == 4) {
			(reinterpret_cast<char *>(&ret))[0] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[1] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[2] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[3] = getc(rndDev);
		} else if (sizeof(unsigned int) == 8) {
			(reinterpret_cast<char *>(&ret))[0] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[1] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[2] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[3] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[4] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[5] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[6] = getc(rndDev);
			(reinterpret_cast<char *>(&ret))[7] = getc(rndDev);
		} else {
			printWarn(string(__FILE__) + ":" + tostr(__LINE__)
				  + ":  sizeof(unsigned int) != 4 && sizeof(unsigned int) != 8");
			rndDev = 0;
			seed = time(0);
			return genRndUInt();
		}
		return ret;
	} else {
		return static_cast<unsigned int>(rand_r(&seed));
	}
}