Differences between urandom-module, uos.urandom and os.urandom?

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
ZKDMun
Posts: 42
Joined: Thu Nov 24, 2016 2:34 pm
Location: Hamburg

Differences between urandom-module, uos.urandom and os.urandom?

Post by ZKDMun » Tue May 01, 2018 12:59 pm

Hi there,

what exactly is the difference between these three functions (urandom-module, uos.random, os.random) to create random numbers?

I am using an ESP8266 and I have implemented some functions to create some random keys of a specific length:

Code: Select all

key_size_bits = 4096

#urandom-module:
def urandomnumb(ksb = key_size_bits):
    import urandom
    by_array = bytearray()
    i = 0
    end_while = int(ksb/8)
    while i < end_while: #maybe the best solution to save RAM-Size, compare with i in range()?
        by_array.append(urandom.getrandbits(8))
        i += 1

    return int.from_bytes(by_array,'big')

#uos.urandom:
def uosurandnumb(ksb = key_size_bits):
    from uos import urandom
    randnumb = urandom(int(ksb/8))
    return int.from_bytes(randnumb,'big')

#os.urandom:
def osurandnumber(ksb = key_size_bits):
    from os import urandom
    randnumb = urandom(int(ksb/8))
    return int.from_bytes(randnumb,'big')
There are some differences in the time the functions will needed (used utime.ticks_us() to get the starting and ending times and so one):
- urandomnumb (urandom-module): between 58k - 61k microseconds
- uosurandnumb (uos.urandom): between 600 - 800 microseconds* *'*
- osurandnumber (os.urandom): between 4.7k - 5k microseconds* *''*

For the urandomnumb()-function, this is because of the while-loop and the process to create the number -- urandom.getrandbits() is limited to 32 bits, so I implemented a special way to generate a longer key, which will be similar to the uos.urandom and os.random-method?

But why did os.urandom need more time to calculate than uos.random? Are both the same - is it better to use uos.random, because it seems to be faster?

And what exactly is the difference between these three functions (urandom-module, uos.random, os.random) to create random numbers?

BTW:
*Every seventh call as a duration of *'*~3000 microseconds (uosurandnumb) and *''*7000 microseconds (osurandnumber) - these are very unusual peaks? Any explanation for this?

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Differences between urandom-module, uos.urandom and os.urandom?

Post by pythoncoder » Thu May 03, 2018 4:37 am

The occasional delays of multiple ms are probably caused by garbage collection. Your code dynamically alters the size of the bytearray which is demanding on the MicroPython memory management. I would allocate a global bytearray at the start of the code, large enough for the longest key, and update the array elements in-place. I suggest you read this in the docs for general guidance on how to write efficient code on devices with limited RAM.
Peter Hinch
Index to my micropython libraries.

User avatar
Roberthh
Posts: 3667
Joined: Sat May 09, 2015 4:13 pm
Location: Rhineland, Europe

Re: Differences between urandom-module, uos.urandom and os.urandom?

Post by Roberthh » Thu May 03, 2018 5:36 am

On the ESP8266, os is just an alias for uos (see https://github.com/micropython/micropyt ... ort.h#L175). So os.urandom() and uos.urandom() point to the same underlying function (starting here: https://github.com/micropython/micropyt ... duos.c#L68). Like @pythoncoder said, the difference is caused by something else,

Post Reply