diff --git a/sys/include/random.h b/sys/include/random.h
index 48b978782fedf1d5dd97b31b1f2e2ef90b71c175..252a8379cfb9af117cf688af11880389673a6b8c 100644
--- a/sys/include/random.h
+++ b/sys/include/random.h
@@ -92,10 +92,7 @@ void random_bytes(uint8_t *buf, size_t size);
  *
  * @return  a random number on [a,b)-interval
  */
-static inline uint32_t random_uint32_range(uint32_t a, uint32_t b)
-{
-    return (random_uint32() % (b - a)) + a;
-}
+uint32_t random_uint32_range(uint32_t a, uint32_t b);
 
 #if PRNG_FLOAT
 /* These real versions are due to Isaku Wada, 2002/01/09 added */
diff --git a/sys/random/random.c b/sys/random/random.c
index dc5e6cf38dfb889d7c22a534a4808be9ea46cbff..ad80880167f90dfeaf262a8791ff6631c159fb6c 100644
--- a/sys/random/random.c
+++ b/sys/random/random.c
@@ -54,3 +54,30 @@ void random_bytes(uint8_t *target, size_t n)
         *target++ = *random_pos++;
     }
 }
+
+uint32_t random_uint32_range(uint32_t a, uint32_t b)
+{
+    assert(a < b);
+
+    uint32_t divisor, rand_val, range = b - a;
+    uint8_t range_msb = bitarithm_msb(range);
+
+    /* check if range is a power of two */
+    if (!(range & (range - 1))) {
+        divisor = (1 << range_msb) - 1;
+    }
+    else if (range_msb < 31) {
+        /* leftshift for next power of two interval */
+        divisor = (1 << (range_msb + 1)) -1;
+    }
+    else {
+        /* disable modulo operation in loop below */
+        divisor = UINT32_MAX;
+    }
+    /* get random numbers until value is smaller than range */
+    do {
+        rand_val = (random_uint32() & divisor);
+    } while (rand_val >= range);
+    /* return random in range [a,b] */
+    return (rand_val + a);
+}