90 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
		
			3.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
#pragma once
 | 
						|
#include <memory>
 | 
						|
#include <mutex>
 | 
						|
#include <random>
 | 
						|
 | 
						|
class XORShiftSeeder; // stolen from https://arvid.io/2018/07/02/better-cxx-prng/
 | 
						|
 | 
						|
class Randomizer
 | 
						|
{
 | 
						|
public:
 | 
						|
	~Randomizer() = default;
 | 
						|
	static Randomizer& GetInstance();
 | 
						|
	enum FillType { _0_to_255, _0_to_127, _128_to_255, ANSIdigit, ANSIuppercase, ANSIlowcase, ANSIchar, ANSIfromAtoF, ANSIfromAtoF_lower
 | 
						|
	};
 | 
						|
	uint8_t GetSingleByte(FillType type);
 | 
						|
private:
 | 
						|
	Randomizer();
 | 
						|
	static std::once_flag m_createonceflag;
 | 
						|
	static std::unique_ptr<Randomizer> m_pInstance;
 | 
						|
	Randomizer(const Randomizer&) = delete;
 | 
						|
	Randomizer(Randomizer&&) = delete;
 | 
						|
	Randomizer& operator=(const Randomizer&) = delete;
 | 
						|
	Randomizer& operator=(Randomizer&&) = delete;
 | 
						|
 | 
						|
	static XORShiftSeeder m_xorshift;
 | 
						|
	static std::uniform_int_distribution<unsigned int> m_distrByte;
 | 
						|
	static std::uniform_int_distribution<unsigned int> m_distrByteHighBit_1;
 | 
						|
	static std::uniform_int_distribution<unsigned int> m_distrByteHighBit_0;
 | 
						|
	static std::uniform_int_distribution<unsigned int> m_ANSIdigit;
 | 
						|
	static std::uniform_int_distribution<unsigned int> m_ANSIuppercase;
 | 
						|
	static std::uniform_int_distribution<unsigned int> m_ANSIlowcase;
 | 
						|
	static std::uniform_int_distribution<unsigned int> m_ANSIchar;
 | 
						|
	static std::uniform_int_distribution<unsigned int> m_ANSIfromAtoF;
 | 
						|
	static std::uniform_int_distribution<unsigned int> m_ANSIfromAtoF_lower;
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
#define RANDBYTE Randomizer::GetInstance().GetSingleByte(Randomizer::FillType::_0_to_255)
 | 
						|
#define RANDBYTEH0 Randomizer::GetInstance().GetSingleByte(Randomizer::FillType::_0_to_127)
 | 
						|
#define RANDBYTEH1 Randomizer::GetInstance().GetSingleByte(Randomizer::FillType::_128_to_255)
 | 
						|
#define RANDANSIDIGIT Randomizer::GetInstance().GetSingleByte(Randomizer::FillType::ANSIdigit)
 | 
						|
#define RANDANSIUPPERCASE Randomizer::GetInstance().GetSingleByte(Randomizer::FillType::ANSIuppercase)
 | 
						|
#define RANDANSILOWCASE Randomizer::GetInstance().GetSingleByte(Randomizer::FillType::ANSIlowcase)
 | 
						|
#define RANDANSICHAR Randomizer::GetInstance().GetSingleByte(Randomizer::FillType::ANSIchar)
 | 
						|
#define RANDHEXSYMBOL (Randomizer::GetInstance().GetSingleByte(Randomizer::FillType::_0_to_127) < 64) ? \
 | 
						|
Randomizer::GetInstance().GetSingleByte(Randomizer::FillType::ANSIfromAtoF_lower) : RANDANSIDIGIT
 | 
						|
#define RANDALNUM RANDBYTEH0 < 64 ? RANDANSIUPPERCASE : (RANDBYTEH0 < 64 ? RANDANSILOWCASE : RANDANSIDIGIT)
 | 
						|
 | 
						|
 | 
						|
 | 
						|
class XORShiftSeeder
 | 
						|
{
 | 
						|
	public:
 | 
						|
		using result_type = uint32_t;
 | 
						|
		static constexpr result_type(min)() { return 0; }
 | 
						|
		static constexpr result_type(max)() { return UINT32_MAX; }
 | 
						|
		friend bool operator==(XORShiftSeeder const &, XORShiftSeeder const &);
 | 
						|
		friend bool operator!=(XORShiftSeeder const &, XORShiftSeeder const &);
 | 
						|
 | 
						|
		XORShiftSeeder() : m_seed(0xc1f651c67c62c6e0ull) {}
 | 
						|
		explicit XORShiftSeeder(std::random_device &rd)
 | 
						|
		{
 | 
						|
			seed(rd);
 | 
						|
		}
 | 
						|
		
 | 
						|
		void seed(std::random_device &rd)
 | 
						|
		{
 | 
						|
			m_seed = uint64_t(rd()) << 31 | uint64_t(rd());
 | 
						|
		}
 | 
						|
 | 
						|
		result_type operator()()
 | 
						|
		{
 | 
						|
			uint64_t result = m_seed * 0xd989bcaef137dcd5ull;
 | 
						|
			m_seed ^= m_seed >> 11;
 | 
						|
			m_seed ^= m_seed << 31;
 | 
						|
			m_seed ^= m_seed >> 18;
 | 
						|
			return uint32_t(result >> 32ull);
 | 
						|
		}
 | 
						|
 | 
						|
		void discard(unsigned long long n)
 | 
						|
		{
 | 
						|
			for (unsigned long long i = 0; i < n; ++i)
 | 
						|
				operator()();
 | 
						|
		}
 | 
						|
 | 
						|
	private:
 | 
						|
		uint64_t m_seed;
 | 
						|
};
 | 
						|
 |