Refactor random library
This commit is contained in:
parent
d629e14533
commit
ca5edb48db
@ -3,16 +3,14 @@
|
||||
#define MESSMER_CPPUTILS_DATA_FIXEDSIZEDATA_H_
|
||||
|
||||
#include <cryptopp/cryptopp/hex.h>
|
||||
#include <cryptopp/cryptopp/osrng.h>
|
||||
#include <string>
|
||||
#include <cstring>
|
||||
#include "../assert/assert.h"
|
||||
#include "../random/RandomPool.h"
|
||||
|
||||
namespace cpputils {
|
||||
|
||||
template<unsigned int SIZE>
|
||||
class FixedSizeData {
|
||||
class FixedSizeData final {
|
||||
public:
|
||||
//Non-virtual destructor because we want objects to be small
|
||||
~FixedSizeData() {}
|
||||
@ -20,8 +18,6 @@ public:
|
||||
static constexpr unsigned int BINARY_LENGTH = SIZE;
|
||||
static constexpr unsigned int STRING_LENGTH = 2 * BINARY_LENGTH; // Hex encoding
|
||||
|
||||
static FixedSizeData<SIZE> CreatePseudoRandom();
|
||||
static FixedSizeData<SIZE> CreateOSRandom();
|
||||
//TODO Test Null()
|
||||
static FixedSizeData<SIZE> Null();
|
||||
|
||||
@ -32,6 +28,7 @@ public:
|
||||
void ToBinary(void *target) const;
|
||||
|
||||
const unsigned char *data() const;
|
||||
unsigned char *data();
|
||||
|
||||
private:
|
||||
FixedSizeData() {}
|
||||
@ -47,20 +44,6 @@ template<unsigned int SIZE> bool operator!=(const FixedSizeData<SIZE> &lhs, cons
|
||||
template<unsigned int SIZE> constexpr unsigned int FixedSizeData<SIZE>::BINARY_LENGTH;
|
||||
template<unsigned int SIZE> constexpr unsigned int FixedSizeData<SIZE>::STRING_LENGTH;
|
||||
|
||||
template<unsigned int SIZE>
|
||||
FixedSizeData<SIZE> FixedSizeData<SIZE>::CreatePseudoRandom() {
|
||||
FixedSizeData<SIZE> result;
|
||||
RandomPool::get(result._data, BINARY_LENGTH);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<unsigned int SIZE>
|
||||
FixedSizeData<SIZE> FixedSizeData<SIZE>::CreateOSRandom() {
|
||||
FixedSizeData<SIZE> result;
|
||||
CryptoPP::OS_GenerateRandomBlock(true, result._data, BINARY_LENGTH);
|
||||
return result;
|
||||
}
|
||||
|
||||
template<unsigned int SIZE>
|
||||
FixedSizeData<SIZE> FixedSizeData<SIZE>::Null() {
|
||||
FixedSizeData<SIZE> result;
|
||||
@ -97,6 +80,11 @@ const unsigned char *FixedSizeData<SIZE>::data() const {
|
||||
return _data;
|
||||
}
|
||||
|
||||
template<unsigned int SIZE>
|
||||
unsigned char *FixedSizeData<SIZE>::data() {
|
||||
return const_cast<unsigned char*>(const_cast<const FixedSizeData<SIZE>*>(this)->data());
|
||||
}
|
||||
|
||||
template<unsigned int SIZE>
|
||||
void FixedSizeData<SIZE>::ToBinary(void *target) const {
|
||||
std::memcpy(target, _data, BINARY_LENGTH);
|
||||
|
3
macros.h
3
macros.h
@ -2,6 +2,9 @@
|
||||
#ifndef MESSMER_CPPUTILS_MACROS_H_
|
||||
#define MESSMER_CPPUTILS_MACROS_H_
|
||||
|
||||
//TODO If possible, make classes final and destructors non-virtual or delete destructors
|
||||
//TODO Use DISALLOW_COPY_AND_ASSIGN where possible
|
||||
|
||||
/**
|
||||
* Disallow the copy and assignment constructors of a class
|
||||
*/
|
||||
|
1
random/OSRandomGenerator.cpp
Normal file
1
random/OSRandomGenerator.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "OSRandomGenerator.h"
|
24
random/OSRandomGenerator.h
Normal file
24
random/OSRandomGenerator.h
Normal file
@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_CPPUTILS_RANDOM_OSRANDOMGENERATOR_H
|
||||
#define MESSMER_CPPUTILS_RANDOM_OSRANDOMGENERATOR_H
|
||||
|
||||
#include "RandomGenerator.h"
|
||||
#include <cryptopp/cryptopp/osrng.h>
|
||||
|
||||
namespace cpputils {
|
||||
class OSRandomGenerator final : public RandomGenerator {
|
||||
public:
|
||||
OSRandomGenerator();
|
||||
|
||||
protected:
|
||||
void get(void *target, size_t bytes) override;
|
||||
};
|
||||
|
||||
inline OSRandomGenerator::OSRandomGenerator() {}
|
||||
|
||||
inline void OSRandomGenerator::get(void *target, size_t bytes) {
|
||||
CryptoPP::OS_GenerateRandomBlock(true, (byte*)target, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
6
random/PseudoRandomPool.cpp
Normal file
6
random/PseudoRandomPool.cpp
Normal file
@ -0,0 +1,6 @@
|
||||
#include "PseudoRandomPool.h"
|
||||
|
||||
namespace cpputils {
|
||||
constexpr size_t PseudoRandomPool::MIN_BUFFER_SIZE;
|
||||
constexpr size_t PseudoRandomPool::MAX_BUFFER_SIZE;
|
||||
}
|
39
random/PseudoRandomPool.h
Normal file
39
random/PseudoRandomPool.h
Normal file
@ -0,0 +1,39 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_CPPUTILS_RANDOM_PSEUDORANDOMPOOL_H
|
||||
#define MESSMER_CPPUTILS_RANDOM_PSEUDORANDOMPOOL_H
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
#include "RandomGenerator.h"
|
||||
#include "ThreadsafeRandomDataBuffer.h"
|
||||
#include "RandomGeneratorThread.h"
|
||||
#include <mutex>
|
||||
|
||||
namespace cpputils {
|
||||
//TODO Test
|
||||
class PseudoRandomPool final : public RandomGenerator {
|
||||
public:
|
||||
PseudoRandomPool();
|
||||
|
||||
protected:
|
||||
void get(void *target, size_t bytes) override;
|
||||
|
||||
private:
|
||||
static constexpr size_t MIN_BUFFER_SIZE = 1*1024*1024; // 1MB
|
||||
static constexpr size_t MAX_BUFFER_SIZE = 2*1024*1024; // 2MB
|
||||
|
||||
ThreadsafeRandomDataBuffer _buffer;
|
||||
RandomGeneratorThread _refillThread;
|
||||
DISALLOW_COPY_AND_ASSIGN(PseudoRandomPool);
|
||||
};
|
||||
|
||||
|
||||
inline void PseudoRandomPool::get(void *target, size_t bytes) {
|
||||
_buffer.get(target, bytes);
|
||||
}
|
||||
|
||||
inline PseudoRandomPool::PseudoRandomPool(): _buffer(), _refillThread(&_buffer, MIN_BUFFER_SIZE, MAX_BUFFER_SIZE) {
|
||||
_refillThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
5
random/Random.cpp
Normal file
5
random/Random.cpp
Normal file
@ -0,0 +1,5 @@
|
||||
#include "Random.h"
|
||||
|
||||
namespace cpputils {
|
||||
std::mutex Random::_mutex;
|
||||
}
|
31
random/Random.h
Normal file
31
random/Random.h
Normal file
@ -0,0 +1,31 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_CPPUTILS_RANDOM_RANDOM_H
|
||||
#define MESSMER_CPPUTILS_RANDOM_RANDOM_H
|
||||
|
||||
#include "PseudoRandomPool.h"
|
||||
#include "OSRandomGenerator.h"
|
||||
#include "../data/FixedSizeData.h"
|
||||
#include "../data/Data.h"
|
||||
#include <mutex>
|
||||
|
||||
namespace cpputils {
|
||||
class Random {
|
||||
public:
|
||||
static PseudoRandomPool &PseudoRandom() {
|
||||
std::unique_lock <std::mutex> lock(_mutex);
|
||||
static PseudoRandomPool random;
|
||||
return random;
|
||||
}
|
||||
|
||||
static OSRandomGenerator &OSRandom() {
|
||||
std::unique_lock <std::mutex> lock(_mutex);
|
||||
static OSRandomGenerator random;
|
||||
return random;
|
||||
}
|
||||
|
||||
private:
|
||||
static std::mutex _mutex;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
1
random/RandomGenerator.cpp
Normal file
1
random/RandomGenerator.cpp
Normal file
@ -0,0 +1 @@
|
||||
#include "RandomGenerator.h"
|
32
random/RandomGenerator.h
Normal file
32
random/RandomGenerator.h
Normal file
@ -0,0 +1,32 @@
|
||||
#ifndef MESSMER_CPPUTILS_RANDOM_RANDOMGENERATOR_H
|
||||
#define MESSMER_CPPUTILS_RANDOM_RANDOMGENERATOR_H
|
||||
|
||||
#include "../data/FixedSizeData.h"
|
||||
#include "../data/Data.h"
|
||||
|
||||
namespace cpputils {
|
||||
class RandomGenerator {
|
||||
public:
|
||||
template<size_t SIZE> FixedSizeData<SIZE> getFixedSize();
|
||||
Data get(size_t size);
|
||||
|
||||
protected:
|
||||
virtual void get(void *target, size_t bytes) = 0;
|
||||
private:
|
||||
static std::mutex _mutex;
|
||||
};
|
||||
|
||||
template<size_t SIZE> inline FixedSizeData<SIZE> RandomGenerator::getFixedSize() {
|
||||
FixedSizeData<SIZE> result = FixedSizeData<SIZE>::Null();
|
||||
get(result.data(), SIZE);
|
||||
return result;
|
||||
}
|
||||
|
||||
inline Data RandomGenerator::get(size_t size) {
|
||||
Data result(size);
|
||||
get(result.data(), size);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -1,8 +0,0 @@
|
||||
#include "RandomPool.h"
|
||||
|
||||
namespace cpputils {
|
||||
|
||||
constexpr size_t RandomPool::MIN_BUFFER_SIZE;
|
||||
constexpr size_t RandomPool::MAX_BUFFER_SIZE;
|
||||
std::mutex RandomPool::_mutex;
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
#pragma once
|
||||
#ifndef MESSMER_CPPUTILS_RANDOM_RANDOMPOOL_H
|
||||
#define MESSMER_CPPUTILS_RANDOM_RANDOMPOOL_H
|
||||
|
||||
#include <boost/thread.hpp>
|
||||
#include "ThreadsafeRandomDataBuffer.h"
|
||||
#include "RandomGeneratorThread.h"
|
||||
#include <mutex>
|
||||
|
||||
namespace cpputils {
|
||||
//TODO Test
|
||||
class RandomPool final {
|
||||
public:
|
||||
static void get(void *target, size_t bytes);
|
||||
|
||||
private:
|
||||
static constexpr size_t MIN_BUFFER_SIZE = 1*1024*1024; // 1MB
|
||||
static constexpr size_t MAX_BUFFER_SIZE = 2*1024*1024; // 2MB
|
||||
|
||||
RandomPool();
|
||||
static RandomPool &singleton();
|
||||
static std::mutex _mutex;
|
||||
|
||||
ThreadsafeRandomDataBuffer _buffer;
|
||||
RandomGeneratorThread _refillThread;
|
||||
DISALLOW_COPY_AND_ASSIGN(RandomPool);
|
||||
};
|
||||
|
||||
inline RandomPool &RandomPool::singleton() {
|
||||
std::unique_lock<std::mutex> lock(_mutex);
|
||||
static RandomPool singleton;
|
||||
return singleton;
|
||||
}
|
||||
|
||||
inline void RandomPool::get(void *target, size_t bytes) {
|
||||
singleton()._buffer.get(target, bytes);
|
||||
}
|
||||
|
||||
inline RandomPool::RandomPool(): _buffer(), _refillThread(&_buffer, MIN_BUFFER_SIZE, MAX_BUFFER_SIZE) {
|
||||
_refillThread.start();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
@ -33,15 +33,6 @@ public:
|
||||
|
||||
constexpr unsigned int FixedSizeDataTest::SIZE;
|
||||
|
||||
TEST_F(FixedSizeDataTest, CanGenerateRandomDataWithoutCrashing) {
|
||||
FixedSizeData<SIZE> result = FixedSizeData<SIZE>::CreatePseudoRandom();
|
||||
}
|
||||
|
||||
TEST_F(FixedSizeDataTest, CreatedRandomDatasHaveCorrectLength) {
|
||||
FixedSizeData<SIZE> data = FixedSizeData<SIZE>::CreatePseudoRandom();
|
||||
EXPECT_EQ(FixedSizeData<SIZE>::STRING_LENGTH, data.ToString().size());
|
||||
}
|
||||
|
||||
TEST_F(FixedSizeDataTest, EqualsTrue) {
|
||||
FixedSizeData<SIZE> DATA1_1 = FixedSizeData<SIZE>::FromString(DATA1_AS_STRING);
|
||||
FixedSizeData<SIZE> DATA1_2 = FixedSizeData<SIZE>::FromString(DATA1_AS_STRING);
|
||||
|
@ -1,3 +1,3 @@
|
||||
#include "../../random/RandomPool.h"
|
||||
#include "../../random/Random.h"
|
||||
|
||||
// Test the header can be included without needing additional dependencies
|
Loading…
Reference in New Issue
Block a user