# A cryptographic version of RANDOM()

**URL:** <https://clarionhub.com/t/a-cryptographic-version-of-random/8300>\
**Category:** code\
**Tags:** encryption, winapi, code\
**Created:** [June 17, 2025, 5:32am UTC](https://clarionhub.com/t/a-cryptographic-version-of-random/8300 "2025-06-17T05:32:54Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![CarlosGtrz](https://clarionhub.com/user_avatar/clarionhub.com/carlosgtrz/32/5870_2.png) [@CarlosGtrz](https://clarionhub.com/u/CarlosGtrz)\
**Post date:** [June 17, 2025, 5:32am UTC](https://clarionhub.com/t/a-cryptographic-version-of-random/8300/1 "2025-06-17T05:32:54Z")

</div>

While [fixing MakeSGuid](https://clarionhub.com/t/another-lexicographically-sortable-unique-id-generator/7503/5) I tested [`BCryptGenRandom`](https://learn.microsoft.com/en-us/windows/win32/api/bcrypt/nf-bcrypt-bcryptgenrandom) and found it's straightforward to use in Clarion for generating cryptographically secure random numbers.

Clarion's built-in `RANDOM` function uses a simple pseudo-random algorithm that can produce predictable patterns, particularly problematic in multithreaded applications where multiple threads might generate similar sequences.

Since a `LONG` is 4 bytes, we can easily use `BCryptGenRandom` to fill those bytes with cryptographic-quality random data to get a random integer, and then scale the integer to a specific range, like Clarion:

```clarion
!!! <summary>
!!! Returns a cryptographically secure random integer.
!!! </summary>
!!! <param name="low">A numeric constant, variable, or expression for the lower boundary of the range.</param>
!!! <param name="high">A numeric constant, variable, or expression for the upper boundary of the range.</param>
!!! <returns>A random LONG integer between the low and high values, inclusively.</returns>  
cRandom PROCEDURE(LONG low, LONG high)!,LONG
randomData STRING(4),AUTO
randomLong LONG,OVER(randomData)
range LONG,AUTO
  CODE
    BCryptGenRandom(0,randomData,4,BCRYPT_USE_SYSTEM_PREFERRED_RNG) !Get 4 cryptographic random bytes
    range = high - low + 1
    randomLong %= range
    randomLong += low
    RETURN randomLong

```

Performance testing shows `cRandom` is approximately 24 times slower than `RANDOM`, making it useful for scenarios where random distribution is more important than speed.

The complete code and test project are available on [GitHub](https://github.com/CarlosGtrz/cRandom). To integrate into your application:

1. Copy `bcryptrandom.lib` to `accessory\lib` or your app folder
2. Copy `cRandom.inc` and `cRandom.clw` to `accessory\libsrc\win` or your app folder.
3. Add `INCLUDE('cRandom.inc'),ONCE` to your global map
