linuxbashfunctionrandomrandom-seed

How can you improve the uniform distribution of a given random function?


The question is related on Linux like Debian, bash and a given function which use RANDOM.

Every improvement should use bash only.

Given are the follow function:

getRND(){
    min="${1:-1}"   ## min is the first parameter, or 1 if no parameter is given           
    max="${2:-100}" ## max is the second parameter, or 100 if no parameter is given
    rnd_count=$((RANDOM%(max-min+1)+min));
    echo "$rnd_count"
}

var=$(getRND -10 10) # Call the function
echo $var # output

How too:

The solution is sought for Linux systems on which no bash 5.1 is installed already and therefore no SRANDOM can be used up to now.


Solution

  • what can be improved on a given random function to make it more random or for a bigger range or something else?

    and therefore no SRANDOM can be used up to now.

    How to improve the randomness of the fuction above, if possible ?

    Sooo write your own SRANDOM with your own semantics. Ex:

    srandom() {
       # take random number from /dev/urandom
       # we take only just 4 bytes - one 2^32 number
       printf "%d\n" "0x$(
           dd if=/dev/urandom of=/dev/stdout bs=4 count=1 status=none |
           xxd -p)"
    }
    

    and then:

    normalize_value(){
       ...
       rnd=$(srandom)
       rnd_count=$((rnd / ...))
    }
    

    Accepting a wider range of numbers

    If you are not happy with the way shell arithmetic expansion works, then... use a different tool. bc calculator has unlimited range.

    rnd_count=$(echo "
         # see https://superuser.com/questions/31445/gnu-bc-modulo-with-scale-other-than-0
         scale=0; 
         # super big random number from three 2^32 numbers
         rnd = $(srandom) * 2^(32*2) +  $(srandom) * 2^32 + $(srandom)
         rnd % ($max - $min + 1) + $min
         " | bc)
    

    You can write your own C program with getrandom() and compile it on the fly echo "int main() { stuff(); }" | gcc -xc - && ./a.out; rm ./a.out basically granting you any semantics you want. There are also other scripting languages, like perl, python, ruby, all most probably with their own big-number libraries and urandom number generation implementations. Sky the limit.

    Every improvement should use bash only.

    Is from my perspective a pointless limitation - overall, I am paid for results, not really "how" I solve problems. Anyway, you could, giving you a bunch of ideas how to proceed: