[random] introduce template-based NonCrypto random APIs (#13142)

This commit introduces a new set of template-based APIs for
non-cryptographic random number generation in the `Random::NonCrypto`
namespace. These new methods provide a cleaner, type-safe, and more
robust interface compared to the previous methods.

Key additions:
- `Generate<UintType>()`: Returns a random value of the given
  unsigned integer type (`uint8_t`, `uint16_t`, or `uint32_t`).
- `GenerateUpToExcluding<UintType>(aMax)`: Returns a random value in
  the range `[0, aMax)`.
- `GenerateFromMinUpToExcluding<UintType>(aMin, aMax)`: Returns a
  random value in the range `[aMin, aMax)`.
- `GenerateInClosedRange<UintType>(aMin, aMax)`: Returns a random
  value in the closed range `[aMin, aMax]`.

The introduction of `GenerateInClosedRange` is an improvement as it
safely handles ranges up to the maximum value of the integer type
(e.g., `0xffff`) without the risk of overflow.

All call sites across the OpenThread core stack and tests have been
updated to adopt these new APIs. The public `otRandomNonCrypto`
functions are also updated to leverage the new internal methods.

Doxygen documentation is added for all new template methods,
detailing their behavior, including edge cases where the upper bound
is smaller than or equal to the lower bound.
This commit is contained in:
Abtin Keshavarzian
2026-05-25 19:39:59 -07:00
committed by GitHub
parent 9d95a19e52
commit 4de7bc578e
46 changed files with 393 additions and 141 deletions
+6 -6
View File
@@ -37,25 +37,25 @@
using namespace ot;
uint32_t otRandomNonCryptoGetUint32(void) { return Random::NonCrypto::GetUint32(); }
uint32_t otRandomNonCryptoGetUint32(void) { return Random::NonCrypto::Generate<uint32_t>(); }
uint8_t otRandomNonCryptoGetUint8(void) { return Random::NonCrypto::GetUint8(); }
uint8_t otRandomNonCryptoGetUint8(void) { return Random::NonCrypto::Generate<uint8_t>(); }
uint16_t otRandomNonCryptoGetUint16(void) { return Random::NonCrypto::GetUint16(); }
uint16_t otRandomNonCryptoGetUint16(void) { return Random::NonCrypto::Generate<uint16_t>(); }
uint8_t otRandomNonCryptoGetUint8InRange(uint8_t aMin, uint8_t aMax)
{
return Random::NonCrypto::GetUint8InRange(aMin, aMax);
return Random::NonCrypto::GenerateFromMinUpToExcluding(aMin, aMax);
}
uint16_t otRandomNonCryptoGetUint16InRange(uint16_t aMin, uint16_t aMax)
{
return Random::NonCrypto::GetUint16InRange(aMin, aMax);
return Random::NonCrypto::GenerateFromMinUpToExcluding(aMin, aMax);
}
uint32_t otRandomNonCryptoGetUint32InRange(uint32_t aMin, uint32_t aMax)
{
return Random::NonCrypto::GetUint32InRange(aMin, aMax);
return Random::NonCrypto::GenerateFromMinUpToExcluding(aMin, aMax);
}
void otRandomNonCryptoFillBuffer(uint8_t *aBuffer, uint16_t aSize) { Random::NonCrypto::FillBuffer(aBuffer, aSize); }
+1 -7
View File
@@ -63,13 +63,7 @@ exit:
uint16_t Config::SelectRandomReregistrationDelay(void) const
{
uint16_t delay = 1;
VerifyOrExit(mReregistrationDelay > 1);
delay = 1 + Random::NonCrypto::GetUint16InRange(0, mReregistrationDelay);
exit:
return delay;
return Random::NonCrypto::GenerateInClosedRange<uint16_t>(1, mReregistrationDelay);
}
#if OT_SHOULD_LOG_AT(OT_LOG_LEVEL_INFO)
+2 -3
View File
@@ -47,7 +47,7 @@ Local::Local(Instance &aInstance)
: InstanceLocator(aInstance)
, mIsServiceAdded(false)
, mState(kStateDisabled)
, mSequenceNumber(Random::NonCrypto::GetUint8() % 127)
, mSequenceNumber(Random::NonCrypto::GenerateUpToExcluding<uint8_t>(127))
, mRegistrationJitter(kDefaultRegistrationJitter)
, mReregistrationDelay(kDefaultRegistrationDelay)
, mRegistrationTimeout(0)
@@ -266,8 +266,7 @@ void Local::UpdateState(void)
}
else
{
mRegistrationTimeout =
1 + Random::NonCrypto::GetUint16InRange(0, static_cast<uint16_t>(mRegistrationJitter));
mRegistrationTimeout = Random::NonCrypto::GenerateInClosedRange<uint16_t>(1, mRegistrationJitter);
Get<TimeTicker>().RegisterReceiver(TimeTicker::kBbrLocal);
}
}
+3 -3
View File
@@ -120,7 +120,7 @@ void Dhcp6PdClient::EnterState(State aState)
case kStateToSolicit:
ClearServerDuid();
ClearPdPrefix();
mTimer.Start(Random::NonCrypto::GetUint32InRange(0, kMaxDelayFirstSolicit));
mTimer.Start(Random::NonCrypto::GenerateUpToExcluding(kMaxDelayFirstSolicit));
break;
case kStateSoliciting:
@@ -1183,11 +1183,11 @@ uint32_t Dhcp6PdClient::RetxTracker::AddJitter(uint32_t aValue, JitterMode aJitt
switch (aJitterMode)
{
case kPositiveJitter:
randomizedValue += Random::NonCrypto::GetUint32InRange(0, jitter);
randomizedValue += Random::NonCrypto::GenerateUpToExcluding<uint32_t>(jitter);
break;
case kFullJitter:
randomizedValue += Random::NonCrypto::GetUint32InRange(0, 2 * jitter) - jitter;
randomizedValue += Random::NonCrypto::GenerateUpToExcluding<uint32_t>(2 * jitter) - jitter;
break;
}
+1 -1
View File
@@ -986,7 +986,7 @@ void RoutingManager::OmrPrefixManager::Evaluate(void)
{
case kNotAdded:
{
uint32_t delay = Random::NonCrypto::GetUint32InRange(kMinDelayToAdd, kMaxDelayToAdd);
uint32_t delay = Random::NonCrypto::GenerateInClosedRange(kMinDelayToAdd, kMaxDelayToAdd);
mLocalInNetDataState = kToAdd;
mTimer.Start(delay);
+1 -1
View File
@@ -1806,7 +1806,7 @@ void RxRaTracker::RsSender::Start(void)
VerifyOrExit(!IsInProgress());
delay = Random::NonCrypto::GetUint32InRange(0, kMaxStartDelay);
delay = Random::NonCrypto::GenerateUpToExcluding(kMaxStartDelay);
LogInfo("RsSender: Starting - will send first RS in %lu msec", ToUlong(delay));
+3 -3
View File
@@ -124,7 +124,7 @@ CoapBase::CoapBase(Instance &aInstance, Transmitter aTransmitter)
, mResponseCache(aInstance)
, mResourceHandler(nullptr)
, mTransmitter(aTransmitter)
, mMessageId(Random::NonCrypto::GetUint16())
, mMessageId(Random::NonCrypto::Generate<uint16_t>())
#if OPENTHREAD_CONFIG_COAP_BLOCKWISE_TRANSFER_ENABLE
, mLastResponse(nullptr)
#endif
@@ -2045,8 +2045,8 @@ exit:
uint32_t TxParameters::CalculateInitialRetransmissionTimeout(void) const
{
return Random::NonCrypto::GetUint32InRange(
mAckTimeout, mAckTimeout * mAckRandomFactorNumerator / mAckRandomFactorDenominator + 1);
return Random::NonCrypto::GenerateInClosedRange<uint32_t>(mAckTimeout, mAckTimeout * mAckRandomFactorNumerator /
mAckRandomFactorDenominator);
}
uint32_t TxParameters::CalculateExchangeLifetime(void) const
+47 -11
View File
@@ -37,6 +37,8 @@
#include "common/code_utils.hpp"
#include "common/debug.hpp"
#include "common/num_utils.hpp"
#include "common/numeric_limits.hpp"
namespace ot {
namespace Random {
@@ -129,30 +131,64 @@ uint32_t Manager::NonCryptoPrng::GetNext(void)
namespace NonCrypto {
uint8_t GetUint8InRange(uint8_t aMin, uint8_t aMax)
static uint32_t GenerateInRange(uint32_t aMin, uint32_t aMax)
{
OT_ASSERT(aMax > aMin);
uint32_t value;
uint32_t range;
return (aMin + (GetUint8() % (aMax - aMin)));
VerifyOrExit(aMin < aMax, value = aMin);
value = Generate<uint32_t>();
range = aMax - aMin;
VerifyOrExit(range < NumericLimits<uint32_t>::kMax);
value = aMin + (value % (range + 1));
exit:
return value;
}
uint16_t GetUint16InRange(uint16_t aMin, uint16_t aMax)
template <typename UintType> UintType GenerateUpToExcluding(UintType aMax)
{
OT_ASSERT(aMax > aMin);
return (aMin + (GetUint16() % (aMax - aMin)));
return GenerateFromMinUpToExcluding<UintType>(0, aMax);
}
uint32_t GetUint32InRange(uint32_t aMin, uint32_t aMax)
template <typename UintType> UintType GenerateFromMinUpToExcluding(UintType aMin, UintType aMax)
{
OT_ASSERT(aMax > aMin);
return (aMin + (GetUint32() % (aMax - aMin)));
if (aMax > 0)
{
aMax--;
}
return GenerateInClosedRange<UintType>(aMin, aMax);
}
template <typename UintType> UintType GenerateInClosedRange(UintType aMin, UintType aMax)
{
return static_cast<UintType>(GenerateInRange(aMin, aMax));
}
// Explicit instantiations
template uint8_t GenerateUpToExcluding<uint8_t>(uint8_t aMax);
template uint16_t GenerateUpToExcluding<uint16_t>(uint16_t aMax);
template uint32_t GenerateUpToExcluding<uint32_t>(uint32_t aMax);
template uint8_t GenerateFromMinUpToExcluding<uint8_t>(uint8_t aMin, uint8_t aMax);
template uint16_t GenerateFromMinUpToExcluding<uint16_t>(uint16_t aMin, uint16_t aMax);
template uint32_t GenerateFromMinUpToExcluding<uint32_t>(uint32_t aMin, uint32_t aMax);
template uint8_t GenerateInClosedRange<uint8_t>(uint8_t aMin, uint8_t aMax);
template uint16_t GenerateInClosedRange<uint16_t>(uint16_t aMin, uint16_t aMax);
template uint32_t GenerateInClosedRange<uint32_t>(uint32_t aMin, uint32_t aMax);
void FillBuffer(uint8_t *aBuffer, uint16_t aSize)
{
while (aSize-- != 0)
{
*aBuffer++ = GetUint8();
*aBuffer++ = Generate<uint8_t>();
}
}
@@ -163,7 +199,7 @@ uint32_t AddJitter(uint32_t aValue, uint16_t aJitter)
VerifyOrExit(aValue != 0);
aJitter = (aJitter <= aValue) ? aJitter : static_cast<uint16_t>(aValue);
delay = aValue + GetUint32InRange(0, 2 * aJitter + 1) - aJitter;
delay = aValue + GenerateUpToExcluding<uint32_t>(2 * aJitter + 1) - aJitter;
exit:
return delay;
+37 -44
View File
@@ -101,60 +101,53 @@ private:
namespace NonCrypto {
/**
* Generates and returns a random `uint32_t` value.
* Generates and returns a random value of a given unsigned integer type.
*
* @returns A random `uint32_t` value.
* @tparam UintType The unsigned integer type to generate (must be `uint8_t`, `uint16_t`, or `uint32_t`).
*
* @returns A random `UintType` value.
*/
inline uint32_t GetUint32(void) { return Manager::NonCryptoGetUint32(); }
template <typename UintType> inline UintType Generate(void)
{
static_assert(TypeTraits::IsUint<UintType>::kValue, "UintType must be an unsigned int");
static_assert(!TypeTraits::IsSame<UintType, uint64_t>::kValue, "UintType cannot be `uint64_t`");
return static_cast<UintType>(Manager::NonCryptoGetUint32());
}
/**
* Generates and returns a random byte.
* Generates and returns a random value of a given unsigned integer type within range `[0, aMax)`.
*
* @returns A random `uint8_t` value.
* @tparam UintType The unsigned integer type to generate (must be `uint8_t`, `uint16_t`, or `uint32_t`).
*
* @param[in] aMax The upper bound (exclusive). If zero, zero is returned.
*
* @returns A random `UintType` value in the range `[0, aMax)`.
*/
inline uint8_t GetUint8(void) { return static_cast<uint8_t>(GetUint32() & 0xff); }
template <typename UintType> UintType GenerateUpToExcluding(UintType aMax);
/**
* Generates and returns a random value of a given unsigned integer type within range `[aMin, aMax)`.
*
* @tparam UintType The unsigned integer type to generate (must be `uint8_t`, `uint16_t`, or `uint32_t`).
*
* @param[in] aMin The lower bound (inclusive).
* @param[in] aMax The upper bound (exclusive). If @p aMax <= @p aMin, @p aMin is returned.
*
* @returns A random `UintType` value in the range `[aMin, aMax)`.
*/
template <typename UintType> UintType GenerateFromMinUpToExcluding(UintType aMin, UintType aMax);
/**
* Generates and returns a random `uint16_t` value.
* Generates and returns a random value of a given unsigned integer type within a closed range `[aMin, aMax]`.
*
* @returns A random `uint16_t` value.
* @tparam UintType The unsigned integer type to generate (must be `uint8_t`, `uint16_t`, or `uint32_t`).
*
* @param[in] aMin The lower bound (inclusive).
* @param[in] aMax The upper bound (inclusive). If @p aMax < @p aMin, @p aMin is returned.
*
* @returns A random `UintType` value in the range `[aMin, aMax]`.
*/
inline uint16_t GetUint16(void) { return static_cast<uint16_t>(GetUint32() & 0xffff); }
/**
* Generates and returns a random `uint8_t` value within a given range `[aMin, aMax)`.
*
* @param[in] aMin A minimum value (this value can be included in returned random result).
* @param[in] aMax A maximum value (this value is excluded from returned random result).
*
* @returns A random `uint8_t` value in the given range (i.e., aMin <= random value < aMax).
*/
uint8_t GetUint8InRange(uint8_t aMin, uint8_t aMax);
/**
* Generates and returns a random `uint16_t` value within a given range `[aMin, aMax)`.
*
* @note The returned random value can include the @p aMin value but excludes the @p aMax.
*
* @param[in] aMin A minimum value (this value can be included in returned random result).
* @param[in] aMax A maximum value (this value is excluded from returned random result).
*
* @returns A random `uint16_t` value in the given range (i.e., aMin <= random value < aMax).
*/
uint16_t GetUint16InRange(uint16_t aMin, uint16_t aMax);
/**
* Generates and returns a random `uint32_t` value within a given range `[aMin, aMax)`.
*
* @note The returned random value can include the @p aMin value but excludes the @p aMax.
*
* @param[in] aMin A minimum value (this value can be included in returned random result).
* @param[in] aMax A maximum value (this value is excluded from returned random result).
*
* @returns A random `uint32_t` value in the given range (i.e., aMin <= random value < aMax).
*/
uint32_t GetUint32InRange(uint32_t aMin, uint32_t aMax);
template <typename UintType> UintType GenerateInClosedRange(UintType aMin, UintType aMax);
/**
* Fills a given buffer with random bytes.
*
+1 -1
View File
@@ -50,7 +50,7 @@ void TimeTicker::RegisterReceiver(Receiver aReceiver)
if (!mTimer.IsRunning())
{
mTimer.Start(Random::NonCrypto::GetUint32InRange(0, kTickInterval + 1));
mTimer.Start(Random::NonCrypto::GenerateInClosedRange<uint32_t>(0, kTickInterval));
}
}
+8 -7
View File
@@ -216,7 +216,7 @@ void TrickleTimer::Start(Mode aMode, uint32_t aIntervalMin, uint32_t aIntervalMa
mMode = aMode;
// Select interval randomly from range [Imin, Imax].
mInterval = Random::NonCrypto::GetUint32InRange(mIntervalMin, mIntervalMax + 1);
mInterval = Random::NonCrypto::GenerateInClosedRange(mIntervalMin, mIntervalMax);
StartNewInterval();
}
@@ -257,11 +257,12 @@ void TrickleTimer::StartNewInterval(void)
case kModeTrickle:
// Select a random point in the interval taken from the range [I/2, I).
halfInterval = mInterval / 2;
mTimeInInterval =
(halfInterval < mInterval) ? Random::NonCrypto::GetUint32InRange(halfInterval, mInterval) : halfInterval;
mCounter = 0;
mPhase = kBeforeRandomTime;
halfInterval = mInterval / 2;
mTimeInInterval = (halfInterval < mInterval)
? Random::NonCrypto::GenerateFromMinUpToExcluding(halfInterval, mInterval)
: halfInterval;
mCounter = 0;
mPhase = kBeforeRandomTime;
break;
}
@@ -275,7 +276,7 @@ void TrickleTimer::HandleTimer(void)
switch (mMode)
{
case kModePlainTimer:
mInterval = Random::NonCrypto::GetUint32InRange(mIntervalMin, mIntervalMax + 1);
mInterval = Random::NonCrypto::GenerateInClosedRange(mIntervalMin, mIntervalMax);
StartNewInterval();
break;
+1 -1
View File
@@ -331,7 +331,7 @@ Instance::Instance(void)
#endif
#endif
, mIsInitialized(false)
, mId(Random::NonCrypto::GetUint32())
, mId(Random::NonCrypto::Generate<uint32_t>())
{
#if OPENTHREAD_CONFIG_MULTIPLE_INSTANCE_ENABLE && OPENTHREAD_CONFIG_PLATFORM_KEY_REFERENCES_ENABLE
#if OPENTHREAD_CONFIG_MULTIPLE_STATIC_INSTANCE_ENABLE
+1 -1
View File
@@ -80,7 +80,7 @@ uint8_t ChannelMask::ChooseRandomChannel(void) const
VerifyOrExit(!IsEmpty());
randomIndex = Random::NonCrypto::GetUint8InRange(0, GetNumberOfChannels());
randomIndex = Random::NonCrypto::GenerateUpToExcluding(GetNumberOfChannels());
SuccessOrExit(GetNextChannel(channel));
+2 -2
View File
@@ -66,8 +66,8 @@ Mac::Mac(Instance &aInstance)
#endif
, mOperation(kOperationIdle)
, mPendingOperations(0)
, mBeaconSequence(Random::NonCrypto::GetUint8())
, mDataSequence(Random::NonCrypto::GetUint8())
, mBeaconSequence(Random::NonCrypto::Generate<uint8_t>())
, mDataSequence(Random::NonCrypto::Generate<uint8_t>())
, mBroadcastTransmitCount(0)
, mPanId(kPanIdBroadcast)
, mPanChannel(OPENTHREAD_CONFIG_DEFAULT_CHANNEL)
+1 -1
View File
@@ -52,7 +52,7 @@ PanId GenerateRandomPanId(void)
do
{
panId = Random::NonCrypto::GetUint16();
panId = Random::NonCrypto::Generate<uint16_t>();
} while (panId == kPanIdBroadcast);
return panId;
+1 -1
View File
@@ -469,7 +469,7 @@ void SubMac::StartTimerForBackoff(uint8_t aBackoffExponent)
{
uint32_t backoff;
backoff = Random::NonCrypto::GetUint32InRange(0, static_cast<uint32_t>(1UL << aBackoffExponent));
backoff = Random::NonCrypto::GenerateUpToExcluding(static_cast<uint32_t>(1UL << aBackoffExponent));
backoff *= (kUnitBackoffPeriod * Radio::kSymbolTime);
if (mRxOnWhenIdle)
+1 -1
View File
@@ -45,7 +45,7 @@ RegisterLogModule("MeshCoPLeader");
Leader::Leader(Instance &aInstance)
: InstanceLocator(aInstance)
, mTimer(aInstance)
, mSessionId(Random::NonCrypto::GetUint16())
, mSessionId(Random::NonCrypto::Generate<uint16_t>())
{
}
+1 -1
View File
@@ -124,7 +124,7 @@ void Timestamp::AdvanceRandomTicks(void)
{
uint16_t ticks = GetTicks();
ticks += Random::NonCrypto::GetUint32InRange(1, kMaxTicks + 1);
ticks += Random::NonCrypto::GenerateInClosedRange<uint16_t>(1, kMaxTicks);
if (ticks > kMaxTicks)
{
+1 -1
View File
@@ -1789,7 +1789,7 @@ void Client::RecordServerAsLimitedToSingleQuestion(const Ip6::Address &aServerAd
if (mLimitedQueryServers.IsFull())
{
uint8_t randomIndex = Random::NonCrypto::GetUint8InRange(0, mLimitedQueryServers.GetMaxSize());
uint8_t randomIndex = Random::NonCrypto::GenerateUpToExcluding(mLimitedQueryServers.GetMaxSize());
mLimitedQueryServers.Remove(mLimitedQueryServers[randomIndex]);
}
+1 -1
View File
@@ -631,7 +631,7 @@ Error Dso::Connection::AppendPadding(Message &aMessage)
// that its padded length is a multiple of the chosen block
// length.
blockLength = kBlockLengths[Random::NonCrypto::GetUint8InRange(0, GetArrayLength(kBlockLengths))];
blockLength = kBlockLengths[Random::NonCrypto::GenerateUpToExcluding(GetArrayLength(kBlockLengths))];
paddingTlv.Init((blockLength - ((aMessage.GetLength() + sizeof(Tlv)) % blockLength)) % blockLength);
+1 -1
View File
@@ -558,7 +558,7 @@ Error Ip6::FragmentDatagram(Message &aMessage, uint8_t aIpProto)
header.SetNextHeader(kProtoFragment);
fragmentHeader.Init();
fragmentHeader.SetIdentification(Random::NonCrypto::GetUint32());
fragmentHeader.SetIdentification(Random::NonCrypto::Generate<uint32_t>());
fragmentHeader.SetNextHeader(aIpProto);
fragmentHeader.SetMoreFlag();
+1 -1
View File
@@ -448,7 +448,7 @@ void Mpl::HandleRetransmissionTimer(void)
void Mpl::Metadata::GenerateNextTransmissionTime(TimeMilli aCurrentTime, uint8_t aInterval)
{
// Emulate Trickle timer behavior and set up the next retransmission within [0,I) range.
uint8_t t = (aInterval == 0) ? aInterval : Random::NonCrypto::GetUint8InRange(0, aInterval);
uint8_t t = (aInterval == 0) ? aInterval : Random::NonCrypto::GenerateUpToExcluding(aInterval);
// Set transmission time at the beginning of the next interval.
mTransmissionTime = aCurrentTime + static_cast<uint32_t>(mIntervalOffset + t);
+5 -5
View File
@@ -4337,7 +4337,7 @@ Core::RxMessage::ProcessOutcome Core::RxMessage::ProcessQuery(bool aShouldProces
if (shouldDelay)
{
delay = Random::NonCrypto::GetUint16InRange(kMinResponseDelay, kMaxResponseDelay);
delay = Random::NonCrypto::GenerateInClosedRange(kMinResponseDelay, kMaxResponseDelay);
}
for (const Question &question : mQuestions)
@@ -5035,7 +5035,7 @@ void Core::MultiPacketRxMessages::RxMsgEntry::Add(OwnedPtr<RxMessage> &aRxMessag
if (aRxMessagePtr->IsTruncated())
{
mProcessTime += Random::NonCrypto::GetUint32InRange(kMinProcessDelay, kMaxProcessDelay);
mProcessTime += Random::NonCrypto::GenerateInClosedRange(kMinProcessDelay, kMaxProcessDelay);
}
// We push the new `RxMessage` at tail of the list to keep the
@@ -5416,7 +5416,7 @@ TimeMilli Core::RandomizeFirstProbeTxTime(void)
if ((mNextProbeTxTime - now) >= kMaxProbeDelay)
{
mNextProbeTxTime = now + Random::NonCrypto::GetUint32InRange(kMinProbeDelay, kMaxProbeDelay);
mNextProbeTxTime = now + Random::NonCrypto::GenerateInClosedRange(kMinProbeDelay, kMaxProbeDelay);
}
return mNextProbeTxTime;
@@ -5428,7 +5428,7 @@ TimeMilli Core::RandomizeInitialQueryTxTime(void)
if ((mNextQueryTxTime - now) >= kMaxInitialQueryDelay)
{
mNextQueryTxTime = now + Random::NonCrypto::GetUint32InRange(kMinInitialQueryDelay, kMaxInitialQueryDelay);
mNextQueryTxTime = now + Random::NonCrypto::GenerateInClosedRange(kMinInitialQueryDelay, kMaxInitialQueryDelay);
}
return mNextQueryTxTime;
@@ -5550,7 +5550,7 @@ void Core::CacheRecordInfo::UpdateQueryAndFireTimeOn(CacheEntry &aCacheEntry)
if (queryTime > now)
{
queryTime += Random::NonCrypto::GetUint32InRange(0, GetClampedTtl() * kQueryTtlVariation);
queryTime += Random::NonCrypto::GenerateUpToExcluding(GetClampedTtl() * kQueryTtlVariation);
aCacheEntry.ScheduleQuery(queryTime);
break;
}
+1 -1
View File
@@ -365,7 +365,7 @@ uint16_t Translator::AllocateSourcePort(uint16_t aSrcPort)
do
{
port = Random::NonCrypto::GetUint16InRange(kMinTranslationPort, kMaxTranslationPort);
port = Random::NonCrypto::GenerateInClosedRange(kMinTranslationPort, kMaxTranslationPort);
// The NAT64 SHOULD preserve the port parity (odd/even), as
// per Section 4.2.2 of [RFC4787]). Determine if original and
+2 -2
View File
@@ -232,7 +232,7 @@ uint32_t Client::TxJitter::DetermineDelay(void)
mRequestedMax = 0;
}
delay = Random::NonCrypto::GetUint32InRange(kMinTxJitter, maxJitter);
delay = Random::NonCrypto::GenerateInClosedRange(kMinTxJitter, maxJitter);
LogInfo("Use random tx jitter %lu from [%lu, %lu]", ToUlong(delay), ToUlong(kMinTxJitter), ToUlong(maxJitter));
return delay;
@@ -1942,7 +1942,7 @@ void Client::SelectNewMessageId(void)
do
{
mCurMessageId = Random::NonCrypto::GetUint16();
mCurMessageId = Random::NonCrypto::Generate<uint16_t>();
} while (oldId == mCurMessageId);
}
+1 -1
View File
@@ -80,7 +80,7 @@ Server::Server(Instance &aInstance)
, mLeaseTimer(aInstance)
, mOutstandingUpdatesTimer(aInstance)
, mCompletedUpdateTask(aInstance)
, mServiceUpdateId(Random::NonCrypto::GetUint32())
, mServiceUpdateId(Random::NonCrypto::Generate<uint32_t>())
, mPort(kUninitializedPort)
, mState(kStateDisabled)
, mAddressMode(kDefaultAddressMode)
+1 -1
View File
@@ -68,7 +68,7 @@ void AnnounceSenderBase::SendAnnounce(uint8_t aCount)
mCount = aCount;
mChannel = mStartingChannel;
mTimer.Start(Random::NonCrypto::GetUint32InRange(0, mJitter + 1));
mTimer.Start(Random::NonCrypto::GenerateUpToExcluding<uint32_t>(mJitter + 1));
exit:
return;
+2 -1
View File
@@ -732,7 +732,8 @@ void DuaManager::HandleChildDuaAddressEvent(const Child &aChild, ChildDuaAddress
{
if (mChildDuaMask == mChildDuaRegisteredMask)
{
UpdateCheckDelay(Random::NonCrypto::GetUint8InRange(1, BackboneRouter::kParentAggregateDelay));
UpdateCheckDelay(
Random::NonCrypto::GenerateInClosedRange<uint8_t>(1, BackboneRouter::kParentAggregateDelay));
}
mChildDuaMask.Add(childIndex);
+1 -1
View File
@@ -40,7 +40,7 @@ namespace ot {
MessageFramer::MessageFramer(Instance &aInstance)
: InstanceLocator(aInstance)
{
mFragTag = Random::NonCrypto::GetUint16();
mFragTag = Random::NonCrypto::Generate<uint16_t>();
}
void MessageFramer::DetermineMacSourceAddress(const Ip6::Address &aIp6Addr, Mac::Addresses &aMacAddrs) const
+5 -4
View File
@@ -652,7 +652,7 @@ uint32_t Mle::GenerateRandomDelay(uint32_t aMaxDelay) const
{
// Generates a random delay within `[1, aMaxDelay]` (inclusive).
return 1 + Random::NonCrypto::GetUint32InRange(0, aMaxDelay);
return Random::NonCrypto::GenerateInClosedRange<uint32_t>(1, aMaxDelay);
}
void Mle::SetTimeout(uint32_t aTimeout, TimeoutAction aAction)
@@ -2819,7 +2819,7 @@ void Mle::ParentSearch::StartTimer(void)
ExitNow();
}
interval = Random::NonCrypto::GetUint32InRange(0, kJitterInterval);
interval = Random::NonCrypto::GenerateUpToExcluding(kJitterInterval);
if (mIsInBackoff)
{
@@ -4485,7 +4485,8 @@ void Mle::PrevRoleRestorer::SendMulticastLinkRequest(void)
retxDelayMax = kLeaderRetxDelayMax;
}
delay = (mAttempts == 0) ? kLinkRequestTimeout : Random::NonCrypto::GetUint32InRange(retxDelayMin, retxDelayMax);
delay =
(mAttempts == 0) ? kLinkRequestTimeout : Random::NonCrypto::GenerateInClosedRange(retxDelayMin, retxDelayMax);
mTimer.Start(delay);
@@ -4666,7 +4667,7 @@ uint32_t Mle::Attacher::GetStartDelay(void) const
}
#endif // OPENTHREAD_CONFIG_MLE_ATTACH_BACKOFF_ENABLE
jitter = Random::NonCrypto::GetUint32InRange(0, kAttachStartJitter);
jitter = Random::NonCrypto::GenerateUpToExcluding(kAttachStartJitter);
if (jitter + delay > delay) // check for overflow
{
+6 -5
View File
@@ -303,7 +303,7 @@ uint8_t Mle::SelectLeaderId(void) const
#endif
return IsValueInRange(mPreviousRouterId, minId, maxId) ? mPreviousRouterId
: Random::NonCrypto::GetUint8InRange(minId, maxId + 1);
: Random::NonCrypto::GenerateInClosedRange(minId, maxId);
}
uint32_t Mle::SelectPartitionId(void) const
@@ -318,7 +318,7 @@ uint32_t Mle::SelectPartitionId(void) const
else
#endif
{
partitionId = Random::NonCrypto::GetUint32();
partitionId = Random::NonCrypto::Generate<uint32_t>();
}
return partitionId;
@@ -1432,7 +1432,8 @@ void Mle::EstablishRouterLinkOnFtdChild(Router &aRouter, RxInfo &aRxInfo, uint8_
VerifyOrExit(neighborCount < mChildRouterLinks + GradualChildRouterLink::kExtraChildRouterLinks);
VerifyOrExit(LinkQualityForLinkMargin(aLinkMargin) >= kLinkQuality2);
VerifyOrExit(GetCurrentAttachDuration() > GradualChildRouterLink::kWaitDurationAfterAttach);
VerifyOrExit(Random::NonCrypto::GetUint8InRange(0, 100) < GradualChildRouterLink::kProbabilityPercentage);
VerifyOrExit(Random::NonCrypto::GenerateUpToExcluding<uint8_t>(100) <
GradualChildRouterLink::kProbabilityPercentage);
minDelay = GradualChildRouterLink::kMinLinkRequestDelay;
maxDelay = GradualChildRouterLink::kMaxLinkRequestDelay;
@@ -1441,7 +1442,7 @@ void Mle::EstablishRouterLinkOnFtdChild(Router &aRouter, RxInfo &aRxInfo, uint8_
InitNeighbor(aRouter, aRxInfo);
aRouter.SetState(Neighbor::kStateLinkRequest);
aRouter.ClearLinkAcceptTimeout();
mDelayedSender.ScheduleLinkRequest(aRouter, Random::NonCrypto::GetUint32InRange(minDelay, maxDelay));
mDelayedSender.ScheduleLinkRequest(aRouter, Random::NonCrypto::GenerateInClosedRange(minDelay, maxDelay));
exit:
return;
@@ -3981,7 +3982,7 @@ Mle::RoleTransitioner::RoleTransitioner(Instance &aInstance)
{
}
void Mle::RoleTransitioner::StartTimeout(void) { mTimeout = 1 + Random::NonCrypto::GetUint8InRange(0, mJitter); }
void Mle::RoleTransitioner::StartTimeout(void) { mTimeout = 1 + Random::NonCrypto::GenerateUpToExcluding(mJitter); }
bool Mle::RoleTransitioner::IsRouterCountBelowUpgradeThreshold(void) const
{
+2 -2
View File
@@ -169,7 +169,7 @@ void Manager::UpdateProxiedSubscriptions(Child &aChild, const ChildAddressArray
if (hasUnregistered)
{
ScheduleSend(Random::NonCrypto::GetUint16InRange(1, BackboneRouter::kParentAggregateDelay));
ScheduleSend(Random::NonCrypto::GenerateInClosedRange<uint16_t>(1, BackboneRouter::kParentAggregateDelay));
}
exit:
@@ -579,7 +579,7 @@ uint32_t Manager::DetermineRenewDelay(void)
timeout = Clamp<uint32_t>(timeout, BackboneRouter::kMinMlrTimeout, kLongRenewTimeout);
return Random::NonCrypto::GetUint32InRange((timeout / 2) + 1, timeout - kRenewGuardTime);
return Random::NonCrypto::GenerateInClosedRange<uint32_t>((timeout / 2) + 1, timeout - kRenewGuardTime);
}
void Manager::ScheduleNextRegistration(RegistrationRequest aRequest)
+2 -2
View File
@@ -57,8 +57,8 @@ Leader::Leader(Instance &aInstance)
void Leader::Reset(void)
{
mVersion = Random::NonCrypto::GetUint8();
mStableVersion = Random::NonCrypto::GetUint8();
mVersion = Random::NonCrypto::Generate<uint8_t>();
mStableVersion = Random::NonCrypto::Generate<uint8_t>();
SetLength(0);
SignalNetDataChanged();
+1 -1
View File
@@ -321,7 +321,7 @@ void Notifier::ScheduleRouterRoleUpgradeIfEligible(void)
VerifyOrExit(Get<Mle::Mle>().IsChild());
VerifyOrExit(IsEligibleForRouterRoleUpgradeAsBorderRouter() && (mRouterRoleUpgradeTimeout == 0));
mRouterRoleUpgradeTimeout = Random::NonCrypto::GetUint8InRange(1, kRouterRoleUpgradeMaxTimeout + 1);
mRouterRoleUpgradeTimeout = Random::NonCrypto::GenerateInClosedRange<uint8_t>(1, kRouterRoleUpgradeMaxTimeout);
Get<TimeTicker>().RegisterReceiver(TimeTicker::kNetworkDataNotifier);
exit:
+2 -2
View File
@@ -305,7 +305,7 @@ void Publisher::Entry::UpdateState(uint8_t aNumEntries, uint8_t aNumPreferredEnt
if (aNumEntries < aDesiredNumEntries)
{
mUpdateTime = now + Random::NonCrypto::GetUint32InRange(1, kMaxDelayToAdd);
mUpdateTime = now + Random::NonCrypto::GenerateInClosedRange<uint32_t>(1, kMaxDelayToAdd);
SetState(kAdding);
Get<Publisher>().GetTimer().FireAtIfEarlier(mUpdateTime);
LogUpdateTime(now);
@@ -345,7 +345,7 @@ void Publisher::Entry::UpdateState(uint8_t aNumEntries, uint8_t aNumPreferredEnt
if (aDesiredNumEntries > 0)
{
mUpdateTime += Random::NonCrypto::GetUint32InRange(1, kMaxDelayToRemove);
mUpdateTime += Random::NonCrypto::GenerateInClosedRange<uint32_t>(1, kMaxDelayToRemove);
if (aNumPreferredEntries < aDesiredNumEntries)
{
+1 -1
View File
@@ -886,7 +886,7 @@ exit:
Client::Client(Instance &aInstance)
: InstanceLocator(aInstance)
, mQueryId(Random::NonCrypto::GetUint16())
, mQueryId(Random::NonCrypto::Generate<uint16_t>())
{
}
+1 -1
View File
@@ -309,7 +309,7 @@ Mac::TxFrame &RadioSelector::SelectRadio(Message &aMessage, const Mac::Address &
#if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE
if (!selections.Contains(Mac::kRadioTypeTrel) && neighbor->GetSupportedRadioTypes().Contains(Mac::kRadioTypeTrel) &&
(Random::NonCrypto::GetUint8InRange(0, 100) < kTrelProbeProbability))
(Random::NonCrypto::GenerateUpToExcluding<uint8_t>(100) < kTrelProbeProbability))
{
aTxFrames.SetRequiredRadioTypes(selections);
selections.Add(Mac::kRadioTypeTrel);
+2 -2
View File
@@ -41,7 +41,7 @@ RouterTable::RouterTable(Instance &aInstance)
, mRouters(aInstance)
, mChangedTask(aInstance)
, mRouterIdSequenceLastUpdated(0)
, mRouterIdSequence(Random::NonCrypto::GetUint8())
, mRouterIdSequence(Random::NonCrypto::Generate<uint8_t>())
, mEvents(0)
#if OPENTHREAD_CONFIG_REFERENCE_DEVICE_ENABLE
, mMinRouterId(0)
@@ -168,7 +168,7 @@ Router *RouterTable::Allocate(void)
// selected ID with current entry in the list with
// probably `1/numAvailable`.
if (Random::NonCrypto::GetUint8InRange(0, numAvailable) == 0)
if (Random::NonCrypto::GenerateUpToExcluding(numAvailable) == 0)
{
selectedRouterId = routerId;
}
+1 -1
View File
@@ -100,7 +100,7 @@ void ChannelManager::RequestNetworkChannelChange(uint8_t aChannel)
mState = kStateChangeRequested;
mChannel = aChannel;
mTimer.Start(1 + Random::NonCrypto::GetUint32InRange(0, kRequestStartJitterInterval));
mTimer.Start(1 + Random::NonCrypto::GenerateUpToExcluding(kRequestStartJitterInterval));
Get<Notifier>().Signal(kEventChannelManagerNewChannelChanged);
+1 -1
View File
@@ -188,7 +188,7 @@ void JamDetector::HandleTimer(void)
}
}
mTimer.Start(mSampleInterval + Random::NonCrypto::GetUint32InRange(0, kMaxRandomDelay));
mTimer.Start(mSampleInterval + Random::NonCrypto::GenerateUpToExcluding(kMaxRandomDelay));
exit:
return;
+2 -2
View File
@@ -125,11 +125,11 @@ OwnedPtr<Message> PrepareMessage(Node &aNode)
VerifyOrQuit(message != nullptr);
length = Random::NonCrypto::GetUint16InRange(1, kMessageSize);
length = Random::NonCrypto::GenerateFromMinUpToExcluding<uint16_t>(1, kMessageSize);
for (uint16_t i = 0; i < length; i++)
{
SuccessOrQuit(message->Append(Random::NonCrypto::GetUint8()));
SuccessOrQuit(message->Append(Random::NonCrypto::Generate<uint8_t>()));
}
return OwnedPtr<Message>(message);
+3 -3
View File
@@ -144,8 +144,8 @@ static void UpdateSrpRegistration(Node &aNode)
service->mSubTypeLabels = nullptr;
service->mTxtEntries = nullptr;
service->mNumTxtEntries = 0;
service->mPort = Random::NonCrypto::GetUint16InRange(0x100, 0xff00);
service->mSubTypeLabels = &info->mSubTypeLabels[Random::NonCrypto::GetUint8InRange(0, 4)];
service->mPort = Random::NonCrypto::GenerateFromMinUpToExcluding<uint16_t>(0x100, 0xff00);
service->mSubTypeLabels = &info->mSubTypeLabels[Random::NonCrypto::GenerateUpToExcluding<uint8_t>(4)];
SuccessOrQuit(aNode.Get<Srp::Client>().AddService(*service));
}
@@ -154,7 +154,7 @@ static bool ShouldPerform(uint16_t aProbability)
{
// Uses the given probability to randomly decide whether a certain action should be performed.
return Random::NonCrypto::GetUint16InRange(0, 1000) < aProbability;
return Random::NonCrypto::GenerateUpToExcluding<uint16_t>(1000) < aProbability;
}
static const Srp::Server::Host *FindHost(Node &aServer, const char *aName)
+1
View File
@@ -250,6 +250,7 @@ ot_unit_test(pool)
ot_unit_test(power_calibration)
ot_unit_test(priority_queue)
ot_unit_test(pskc)
ot_unit_test(random)
ot_unit_test(routing_manager)
ot_unit_test(seeker)
ot_unit_test(serial_number)
+2 -2
View File
@@ -159,11 +159,11 @@ void CorruptMessage(Message &aMessage)
uint8_t bitOffset;
uint8_t byte;
byteOffset = Random::NonCrypto::GetUint16InRange(0, aMessage.GetLength());
byteOffset = Random::NonCrypto::GenerateUpToExcluding<uint16_t>(aMessage.GetLength());
SuccessOrQuit(aMessage.Read(byteOffset, byte));
bitOffset = Random::NonCrypto::GetUint8InRange(0, kBitsPerByte);
bitOffset = Random::NonCrypto::GenerateUpToExcluding<uint8_t>(kBitsPerByte);
byte ^= (1 << bitOffset);
+225
View File
@@ -0,0 +1,225 @@
/*
* Copyright (c) 2026, The OpenThread Authors.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the copyright holder nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
c * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include "test_platform.h"
#include <openthread/config.h>
#include "test_util.h"
#include "common/code_utils.hpp"
#include "common/num_utils.hpp"
#include "common/numeric_limits.hpp"
#include "common/random.hpp"
namespace ot {
template <typename UintType> void TestRandomNonCryto(const char *aName)
{
static constexpr uint8_t kMaxIters = 6;
Instance *instance = static_cast<Instance *>(testInitInstance());
UintType value;
UintType max = NumericLimits<UintType>::kMax;
VerifyOrQuit(instance != nullptr);
printf("--------------------------------------------------------------------\n\r");
printf("TestRandomNonCryto<%s>()\r\n", aName);
//--------------------------------------------------------------------------
// GenerateUpToExcluding
value = Random::NonCrypto::GenerateUpToExcluding<UintType>(0);
VerifyOrQuit(value == 0);
printf("\r\nGenerateUpToExcluding(100): ");
for (uint8_t iter = 0; iter < kMaxIters; iter++)
{
value = Random::NonCrypto::GenerateUpToExcluding<UintType>(100);
printf("%lu, ", ToUlong(value));
VerifyOrQuit(value < 100);
}
printf("\r\nGenerateUpToExcluding(kMax): ");
for (uint8_t iter = 0; iter < kMaxIters; iter++)
{
value = Random::NonCrypto::GenerateUpToExcluding<UintType>(max);
printf("0x%lx, ", ToUlong(value));
VerifyOrQuit(value < max);
}
//--------------------------------------------------------------------------
// GenerateUpToExcluding
value = Random::NonCrypto::GenerateFromMinUpToExcluding<UintType>(12, 12);
VerifyOrQuit(value == 12);
value = Random::NonCrypto::GenerateFromMinUpToExcluding<UintType>(12, 11);
VerifyOrQuit(value == 12);
value = Random::NonCrypto::GenerateFromMinUpToExcluding<UintType>(12, 0);
VerifyOrQuit(value == 12);
value = Random::NonCrypto::GenerateFromMinUpToExcluding<UintType>(max, 0);
VerifyOrQuit(value == max);
value = Random::NonCrypto::GenerateFromMinUpToExcluding<UintType>(max, max);
VerifyOrQuit(value == max);
for (uint8_t iter = 0; iter < kMaxIters; iter++)
{
value = Random::NonCrypto::GenerateFromMinUpToExcluding<UintType>(iter, iter + 1);
VerifyOrQuit(value == iter);
}
printf("\r\nGenerateFromMinUpToExcluding(100, 105): ");
for (uint8_t iter = 0; iter < kMaxIters; iter++)
{
value = Random::NonCrypto::GenerateFromMinUpToExcluding<UintType>(100, 105);
printf("%lu, ", ToUlong(value));
VerifyOrQuit(value >= 100);
VerifyOrQuit(value < 105);
}
printf("\r\nGenerateFromMinUpToExcluding(max - 2, max): ");
for (uint8_t iter = 0; iter < kMaxIters; iter++)
{
value = Random::NonCrypto::GenerateFromMinUpToExcluding<UintType>(max - 2, max);
printf("0x%lx, ", ToUlong(value));
VerifyOrQuit(value >= max - 2);
VerifyOrQuit(value < max);
}
printf("\r\nGenerateFromMinUpToExcluding(0, max): ");
for (uint8_t iter = 0; iter < kMaxIters; iter++)
{
value = Random::NonCrypto::GenerateFromMinUpToExcluding<UintType>(0, max);
printf("0x%lx, ", ToUlong(value));
VerifyOrQuit(value < max);
}
//--------------------------------------------------------------------------
// GenerateInClosedRange
value = Random::NonCrypto::GenerateInClosedRange<UintType>(101, 101);
VerifyOrQuit(value == 101);
value = Random::NonCrypto::GenerateInClosedRange<UintType>(101, 100);
VerifyOrQuit(value == 101);
value = Random::NonCrypto::GenerateInClosedRange<UintType>(101, 0);
VerifyOrQuit(value == 101);
value = Random::NonCrypto::GenerateInClosedRange<UintType>(max, max);
VerifyOrQuit(value == max);
for (uint8_t iter = 0; iter < kMaxIters; iter++)
{
value = Random::NonCrypto::GenerateInClosedRange<UintType>(iter, iter);
VerifyOrQuit(value == iter);
}
printf("\r\nGenerateInClosedRange(200, 201): ");
for (uint8_t iter = 0; iter < kMaxIters; iter++)
{
value = Random::NonCrypto::GenerateInClosedRange<UintType>(200, 201);
printf("%lu, ", ToUlong(value));
VerifyOrQuit(value >= 200);
VerifyOrQuit(value <= 201);
}
while (true)
{
// Make sure upper bound can be returned
value = Random::NonCrypto::GenerateInClosedRange<UintType>(100, 101);
VerifyOrQuit(value >= 100);
VerifyOrQuit(value <= 101);
if (value == 101)
{
break;
}
}
printf("\r\nGenerateInClosedRange(0, max): ");
for (uint8_t iter = 0; iter < kMaxIters; iter++)
{
value = Random::NonCrypto::GenerateInClosedRange<UintType>(0, max);
printf("0x%lx, ", ToUlong(value));
}
printf("\r\nGenerateInClosedRange(max-1, max): ");
for (uint8_t iter = 0; iter < kMaxIters; iter++)
{
value = Random::NonCrypto::GenerateInClosedRange<UintType>(max - 1, max);
printf("0x%lx, ", ToUlong(value));
VerifyOrQuit(value >= max - 1);
}
while (true)
{
// Make sure upper bound can be returned
value = Random::NonCrypto::GenerateInClosedRange<UintType>(max - 1, max);
VerifyOrQuit(value >= max - 1);
if (value == max)
{
break;
}
}
printf("\r\nTest passed\r\n");
}
} // namespace ot
int main(void)
{
ot::TestRandomNonCryto<uint8_t>("uint8_t");
ot::TestRandomNonCryto<uint16_t>("uint16_t");
ot::TestRandomNonCryto<uint32_t>("uint32_t");
printf("\nAll tests passed.\n");
return 0;
}
+1 -1
View File
@@ -887,7 +887,7 @@ uint32_t GetRandom(uint32_t max)
}
else
{
value = Random::NonCrypto::GetUint32();
value = Random::NonCrypto::Generate<uint32_t>();
}
return value % max;