1 /* $Id: random.cc,v 1.1 2005/07/04 15:00:37 atterer Exp $ -*- C++ -*-
3 |_) /| Copyright (C) 2005 | richard@
4 | \/¯| Richard Atterer | atterer.org
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License, version 2. See the file
12 Pseudo random number generation
20 //______________________________________________________________________
22 void update(MD5Sum& md, uint32 x) {
23 md.update(static_cast<byte>(x));
24 md.update(static_cast<byte>(x >> 8));
25 md.update(static_cast<byte>(x >> 16));
26 md.update(static_cast<byte>(x >> 24));
28 //______________________________________________________________________
39 byte* rptr; // points to one of hashData.r's elements
41 uint32 res; // Bit reservoir
45 Rand(uint32 nr, bool printMessages = false) {
49 rptr = rend = &hashData.r.sum[0] + 16;
55 // Create another 128 semi-random bits in md
57 // Return n semi-random bits, n <= 24
58 uint32 get(size_t n) {
59 while (bitsInRes < n) {
60 if (rptr == rend) thumbScrew();
61 res |= (*rptr++) << bitsInRes;
64 uint32 r = res & ((1 << n) - 1);
69 // Return an integer in the range 0...n-1
70 uint32 rnd(size_t n) {
71 return static_cast<uint32>(static_cast<uint64>(get(24)) * n / 0x1000000);
75 void Rand::thumbScrew() {
77 update(md, hashData.nr);
78 update(md, hashData.serial);
79 md.update(&hashData.r.sum[0], 16 * sizeof(byte));
83 rptr = &hashData.r.sum[0];
84 //cout << '<' << hashData.r << '>' << endl;
86 //______________________________________________________________________
88 int main(int argc, const char* argv[]) {
91 cerr << "Syntax: " << argv[0] << " <nr-of-bytes> [<byteVal>]\n"
92 "nr-of-bytes can have a trailing `k' for kiloBytes\n"
93 "If byteVal is present, not random bytes are written, but bytes with\n"
94 "the specified value." << endl;
97 //____________________
101 const char* p = argv[1];
102 while (*p >= '0' && *p <= '9') {
103 bytesArg = bytesArg * 10 + *p - '0';
111 cerr << "Wrong format for argument 1: `" << argv[1] << '\'' << endl;
114 //cerr << bytesArg << endl;
116 uint32 byteVal = 256;
119 const char* p = argv[2];
120 while (*p >= '0' && *p <= '9') {
121 byteVal = byteVal * 10 + *p - '0';
125 //____________________
128 uint32 randomSeed = 0;
130 fstream randomFile(".random");
131 if (randomFile) randomFile >> randomSeed;
133 Rand rand(randomSeed);
136 if (byteVal == 256) {
137 // Write random bytes
138 while (bytesArg > 0) {
139 uint32 n = (bytesArg > 1024 ? 1024 : bytesArg);
140 for (uint32 i = 0; i < n; ++i) buf[i] = rand.get(8);
141 cout.write((char*)(buf), n);
145 // Write bytes with value of byteVal
146 memset(buf, byteVal, 1024);
147 while (bytesArg > 0) {
148 uint32 n = (bytesArg > 1024 ? 1024 : bytesArg);
149 cout.write((char*)(buf), n);
154 fstream randomFile(".random", fstream::out | fstream::trunc);
156 randomFile << randomSeed;