mIRC Homepage
Posted By: maroon $rand(N1bits,N2bytes).bytes - 05/11/22 01:23 PM
Can there be some kind of syntax for $rand/$rands that just returns the raw bytes obtained from the RNG as an even length hex string, without any calculations done against them prior to being the return value? This would be a 'pure' random value straight from the source without any risk of unknown bias being caused by translating to/from doubles or any rounding, and would be a preferred method when the range size is large and/or a power of 2.

I'm thinking something like $rand(N1,N2).raw where N2 is the number of bytes to return, and N1 is the number of bits to return from that first/topmost byte.

It would request N2 bytes from the RNG, and they would be returned without modification except for N1 being a number 1-8 bitmask to indicate how many bit should be kept from the 1st byte of the return string.

So $rand(8,1).raw would be just a single byte that hasn't been altered, and could be anything from 00 through ff. $rand(7,4) would be 4 bytes where the 1st byte has kept the least 7 bits to be in the range of 00 throuth 7f, and only the top bit has been zeroed. $rand(8,10) would return a raw JSF64 value plus 2 bytes from the next call, and the '8' indicates that the 1st of 10 bytes should not be altered. For $rands(8,10) it would return the 10 raw bytes that it asked from the OS.

--

When someone requests a random number from a range size larger than 2^53, the most likely goal is to ask for a range whose size is an exact 2^n size, so it's wasted effort for the random identifiers to try to calculate what size range they should ask for and then do some math to try to modify the input range into the output range, especially since the most frequent intent from these large ranges is for the range size to be an exact 2^n size that doesn't need manipulating except possibly to strip bits from the most significant byte. By having the bits stripped from the 1st byte of the output, that leaves the output looking like how $base would translate to outbase=16, except there can be leading zeroes so the output length is always N2*2.

This kind of return value would ensure there could be no bias in the output since there's never anything different in the output compared to what was in the input, and each output string would be guaranteed to have the same number of inputs mapped to it, and for N1=8 it would always be a 1:1 relationship.

Returning an even-length hex string makes the 'calculation' of the return string a quick matter of individually displaying each byte as 2 hex digits, without any math needing to calculated a return 'number'.

If you think it's appropriate to build the return string by using only 4-of-8 bytes of the JSF64 return value after XOR'ing both 32-bit halves together, that seems like a reasonable manipulation since it doesn't involve floats, and XOR'ing a pair of 32-bit numbers against each other would not create any uneven in/out mapping relationships.
© mIRC Discussion Forums