/*** Copyright (C) 2021 J Reece Wilson (a/k/a "Reece"). All rights reserved. File: RNG.hpp Date: 2021-6-10 Author: Reece ***/ #pragma once namespace Aurora::RNG { AUKN_SYM void ReadSecureRNG(void *in, AuUInt length); AUKN_SYM void ReadFastRNG(void *in, AuUInt length); template static inline void Read(T(&array)[N]) { if constexpr (fast) { ReadFastRNG(array, N * sizeof(T)); } else { ReadSecureRNG(array, N * sizeof(T)); } } template static inline void Read(T *array, AuUInt length) { if constexpr (fast) { ReadFastRNG(array, length * sizeof(T)); } else { ReadSecureRNG(array, length * sizeof(T)); } } enum class RngStringCharacters { eAlphaCharacters, eAlphaNumericCharacters, eExtendedEntropy, eCount }; static void RngString(char *string, AuUInt length, RngStringCharacters type = RngStringCharacters::eAlphaCharacters) { static std::pair rngSequence[static_cast(RngStringCharacters::eCount)] = { {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 52}, {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 62}, {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890=-+!$%^*.[];:", 75} }; ReadSecureRNG(string, length); const auto &pair = rngSequence[static_cast(type)]; for (auto i = 0; i < length; i++) { auto idx = std::floor(static_cast(reinterpret_cast(string)[i]) / 255.f * static_cast(pair.second - 1)); string[i] = pair.first[static_cast(idx)]; } } static inline AuUInt8 RngByte() { AuUInt8 x[1]; Read(x); return x[0]; } static inline bool RngBoolean() { return RngByte() > 127; } template static inline T &RngArray(T *items, AuUInt count) { return items[static_cast(std::floor(static_cast(RngByte()) / 255.f * static_cast(count - 1)))]; } template static inline T &RngVector(const AuList &items) { return RngArray(items.data(), items.size()); } }