Added Cyril's random number generator (from libretroshare) to libbitdht.

* replaced all calls to rand() by bdRandom::random_u32(), etc.



git-svn-id: http://svn.code.sf.net/p/retroshare/code/branches/v0.5-peernet@4306 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
drbob 2011-06-20 15:19:25 +00:00
parent c9874176b9
commit 4fdbd09879
10 changed files with 186 additions and 143 deletions

View File

@ -29,6 +29,7 @@
#include "bitdht/bdmsgs.h"
#include "util/bdnet.h"
#include "util/bdrandom.h"
#include <string.h>
#include <stdlib.h>
@ -1968,8 +1969,12 @@ void bdNode::genNewToken(bdToken *token)
fprintf(stderr, ")\n");
#endif
// XXX is this a good way to do it?
// Variable length, from 4 chars up to lots... 10?
// leave for the moment, but fix.
std::ostringstream out;
out << std::setw(4) << std::setfill('0') << rand() << std::setw(4) << std::setfill('0') << rand();
out << std::setw(4) << std::setfill('0') << bdRandom::random_u32();
std::string num = out.str();
int len = num.size();
if (len > BITDHT_TOKEN_MAX_LEN)

View File

@ -26,6 +26,7 @@
#include "bitdht/bdpeer.h"
#include "util/bdnet.h"
#include "util/bdrandom.h"
#include "bitdht/bdiface.h"
#include <stdlib.h>
@ -180,136 +181,6 @@ int operator==(const bdId &a, const bdId &b)
}
#if 0
void bdRandomId(bdId *id)
{
bdRandomNodeId(&(id->id));
id->addr.sin_addr.s_addr = rand();
id->addr.sin_port = rand();
return;
}
void bdRandomNodeId(bdNodeId *id)
{
uint32_t *a_data = (uint32_t *) id->data;
for(int i = 0; i < BITDHT_KEY_INTLEN; i++)
{
a_data[i] = rand();
}
return;
}
/* fills in dbNodeId r, with XOR of a and b */
int bdDistance(const bdNodeId *a, const bdNodeId *b, bdMetric *r)
{
uint8_t *a_data = (uint8_t *) a->data;
uint8_t *b_data = (uint8_t *) b->data;
uint8_t *ans = (uint8_t *) r->data;
for(int i = 0; i < BITDHT_KEY_LEN; i++)
{
*(ans++) = *(a_data++) ^ *(b_data++);
}
return 1;
}
void bdRandomMidId(const bdNodeId *target, const bdNodeId *other, bdNodeId *midId)
{
bdMetric dist;
/* get distance between a & c */
bdDistance(target, other, &dist);
/* generate Random Id */
bdRandomNodeId(midId);
/* zero bits of Random Id until under 1/2 of distance
* done in bytes for ease... matches one extra byte than distance = 0
* -> hence wierd order of operations
*/
bool done = false;
for(int i = 0; i < BITDHT_KEY_LEN; i++)
{
midId->data[i] = target->data[i];
if (dist.data[i] != 0)
break;
}
}
std::string bdConvertToPrintable(std::string input)
{
std::ostringstream out;
for(uint32_t i = 0; i < input.length(); i++)
{
/* sensible chars */
if ((input[i] > 31) && (input[i] < 127))
{
out << input[i];
}
else
{
out << "[0x" << std::hex << (uint32_t) input[i] << "]";
out << std::dec;
}
}
return out.str();
}
void bdPrintNodeId(std::ostream &out, const bdNodeId *a)
{
for(int i = 0; i < BITDHT_KEY_LEN; i++)
{
out << std::setw(2) << std::setfill('0') << std::hex << (uint32_t) (a->data)[i];
}
out << std::dec;
return;
}
void bdPrintId(std::ostream &out, const bdId *a)
{
bdPrintNodeId(out, &(a->id));
out << " ip:" << inet_ntoa(a->addr.sin_addr);
out << ":" << ntohs(a->addr.sin_port);
return;
}
/* returns 0-160 depending on bucket */
int bdBucketDistance(const bdNodeId *a, const bdNodeId *b)
{
bdMetric m;
bdDistance(a, b, &m);
return bdBucketDistance(&m);
}
/* returns 0-160 depending on bucket */
int bdBucketDistance(const bdMetric *m)
{
for(int i = 0; i < BITDHT_KEY_BITLEN; i++)
{
int bit = BITDHT_KEY_BITLEN - i - 1;
int byte = i / 8;
int bbit = 7 - (i % 8);
unsigned char comp = (1 << bbit);
#ifdef BITDHT_DEBUG
fprintf(stderr, "bdBucketDistance: bit:%d byte:%d bbit:%d comp:%x, data:%x\n", bit, byte, bbit, comp, m->data[byte]);
#endif
if (comp & m->data[byte])
{
return bit;
}
}
return 0;
}
#endif
bdBucket::bdBucket()
{
@ -1114,7 +985,7 @@ bool bdSpace::findRandomPeerWithFlag(bdId &id, uint32_t withFlag)
if(totalcount == 0)
return false ;
uint32_t rnd = rand() % totalcount;
uint32_t rnd = bdRandom::random_u32() % totalcount;
uint32_t i = 0;
uint32_t buck = 0;

View File

@ -26,10 +26,12 @@
#include "bitdht/bdstddht.h"
#include "bitdht/bdpeer.h"
#include "util/bdrandom.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <iostream>
#include <sstream>
@ -42,9 +44,8 @@
void bdStdRandomId(bdId *id)
{
bdStdRandomNodeId(&(id->id));
id->addr.sin_addr.s_addr = rand();
id->addr.sin_port = rand();
id->addr.sin_addr.s_addr = bdRandom::random_u32();
id->addr.sin_port = (bdRandom::random_u32() % USHRT_MAX);
return;
}
@ -54,7 +55,7 @@ void bdStdRandomNodeId(bdNodeId *id)
uint32_t *a_data = (uint32_t *) id->data;
for(int i = 0; i < BITDHT_KEY_INTLEN; i++)
{
a_data[i] = rand();
a_data[i] = bdRandom::random_u32();
}
return;
}

View File

@ -100,6 +100,7 @@ HEADERS += \
bitdht/bdhistory.h \
util/bdnet.h \
util/bdthreads.h \
util/bdrandom.h \
udp/udplayer.h \
udp/udpstack.h \
udp/udpbitdht.h \
@ -117,8 +118,9 @@ SOURCES += \
bitdht/bdmanager.cc \
bitdht/bdstddht.cc \
bitdht/bdhistory.cc \
util/bdnet.cc \
util/bdnet.cc \
util/bdthreads.cc \
util/bdrandom.cc \
udp/udplayer.cc \
udp/udpstack.cc \
udp/udpbitdht.cc \

View File

@ -27,6 +27,7 @@
#include "bitdht/bdmanager.h"
#include "bitdht/bdstddht.h"
#include "udp/udplayer.h"
#include "util/bdrandom.h"
#include <stdlib.h>
@ -85,7 +86,7 @@ int main(int argc, char **argv)
{
for(j = 0; j < 2; j++)
{
int peeridx = rand() % n_nodes;
int peeridx = bdRandom::random_u32() % n_nodes;
for(i = 0, it = nodes.begin();
(i < peeridx) && (it != nodes.end()); i++, it++)
{

View File

@ -26,6 +26,7 @@
#include "bitdht/bdnode.h"
#include "bitdht/bdstddht.h"
#include "util/bdrandom.h"
#include <stdlib.h>
@ -87,7 +88,7 @@ int main(int argc, char **argv)
for(j = 0; j < 5; j++)
{
int peeridx = rand() % n_nodes;
int peeridx = bdRand::random_u32() % n_nodes;
bdId pid = portIdx[peeridx];
node->addPotentialPeer(&pid, NULL);

View File

@ -72,8 +72,6 @@ int main(int argc, char **argv)
bool doThreadJoin = false;
int noQueries = 0;
srand(time(NULL));
while((c = getopt(argc, argv,"rjp:b:u:q:")) != -1)
{
switch (c)

View File

@ -24,6 +24,7 @@
*/
#include "udp/udplayer.h"
#include "util/bdrandom.h"
#include <iostream>
#include <sstream>
@ -527,8 +528,7 @@ int LossyUdpLayer::receiveUdpPacket(void *data, int *size, struct sockaddr_in &f
{
if (0 < UdpLayer::receiveUdpPacket(data, size, from))
{
double prob = (1.0 * (rand() / (RAND_MAX + 1.0)));
float prob = bdRandom::random_f32();
if (prob < lossFraction)
{
/* discard */

View File

@ -0,0 +1,93 @@
#include <stdlib.h>
#include <string>
#include <unistd.h>
#include "util/bdrandom.h"
uint32_t bdRandom::index = 0 ;
std::vector<uint32_t> bdRandom::MT(bdRandom::N,0u) ;
bdMutex bdRandom::rndMtx ;
#ifdef WINDOWS_SYS
static bool auto_seed = bdRandom::seed( (time(NULL) + ((uint32_t) pthread_self().p)*0x1293fe)^0x18e34a12 ) ;
#else
#ifdef __APPLE__
static bool auto_seed = bdRandom::seed( (time(NULL) + pthread_mach_thread_np(pthread_self())*0x1293fe + (getpid()^0x113ef76b))^0x18e34a12 ) ;
#else
static bool auto_seed = bdRandom::seed( (time(NULL) + pthread_self()*0x1293fe + (getpid()^0x113ef76b))^0x18e34a12 ) ;
#endif
#endif
bool bdRandom::seed(uint32_t s)
{
bdStackMutex mtx(rndMtx) ;
MT.resize(N,0) ; // because MT might not be already resized
uint32_t j ;
MT[0]= s & 0xffffffffUL;
for (j=1; j<N; j++)
MT[j] = (1812433253UL * (MT[j-1] ^ (MT[j-1] >> 30)) + j) & 0xffffffffUL ;
return true ;
}
void bdRandom::locked_next_state()
{
for(uint32_t i=0;i<N;++i)
{
uint32_t y = ((MT[i]) & UMASK) | ((MT[(i+1)%(int)N]) & LMASK) ;
MT[i] = MT[(i + M) % (int)N] ^ (y >> 1) ;
if((y & 1) == 1)
MT[i] = MT[i] ^ 0x9908b0df ;
}
index = 0 ;
}
uint32_t bdRandom::random_u32()
{
uint32_t y;
{
bdStackMutex mtx(rndMtx) ;
y = MT[index++] ;
if(index == N)
locked_next_state();
}
// Tempering
y ^= (y >> 11);
y ^= (y << 7 ) & 0x9d2c5680UL;
y ^= (y << 15) & 0xefc60000UL;
y ^= (y >> 18);
return y;
}
uint64_t bdRandom::random_u64()
{
return ((uint64_t)random_u32() << 32ul) + random_u32() ;
}
float bdRandom::random_f32()
{
return random_u32() / (float)(~(uint32_t)0) ;
}
double bdRandom::random_f64()
{
return random_u64() / (double)(~(uint64_t)0) ;
}
std::string bdRandom::random_alphaNumericString(uint32_t len)
{
std::string s = "" ;
for(uint32_t i=0;i<len;++i)
s += (char)( (random_u32()%94) + 33) ;
return s ;
}

View File

@ -0,0 +1,71 @@
#ifndef BITDHT_UTILS_BDRANDOM_H
#define BITDHT_UTILS_BDRANDOM_H
/****************************************************************
* libbitdht is distributed under the following license:
*
* Copyright (C) 2010 Cyril Soler <csoler@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
****************************************************************/
/* This Source Code is basically a direct copy of libretroshare's RsRandom.
* the function names have just been renamed. drbob
*/
// bdRandom contains a random number generator that is
// - thread safe
// - system independant
// - fast
// - cryptographically safe
//
// The implementation is adapted from the Mersenne Twister page of Wikipedia.
//
// http://en.wikipedia.org/wiki/Mersenne_twister
#include <vector>
#include "util/bdthreads.h"
class bdRandom
{
public:
static uint32_t random_u32() ;
static uint64_t random_u64() ;
static float random_f32() ;
static double random_f64() ;
static bool seed(uint32_t s) ;
static std::string random_alphaNumericString(uint32_t length) ;
private:
static bdMutex rndMtx ;
static const uint32_t N = 624;
static const uint32_t M = 397;
static const uint32_t MATRIX_A = 0x9908b0dfUL;
static const uint32_t UMASK = 0x80000000UL;
static const uint32_t LMASK = 0x7fffffffUL;
static void locked_next_state() ;
static uint32_t index ;
static std::vector<uint32_t> MT ;
};
#endif