# Generating random numbers in Rell · Learn Chromia

> Games, lotteries, and cryptographic protocols built on a blockchain need random numbers that are hard to predict yet reproducible. On Chromia, you can…

Source: https://chromia.com/learn/random-number-generation/introduction/

Generating random numbers in RellLesson 1 of 1

1. [01Generating random numbers in Rell](https://chromia.com/learn/random-number-generation/introduction/)

[Learn](https://chromia.com/learn/)[Generating random numbers in Rell](https://chromia.com/learn/random-number-generation/)

01 / 01Guide

# Generating random numbers in Rell

Games, lotteries, and cryptographic protocols built on a blockchain need random numbers that are hard to predict yet reproducible. On Chromia, you can produce them with custom Rell functions. These functions draw on blockchain context values such as block height, timestamp, and block IDs, so their output is difficult to predict but always identical for identical inputs.

warning

These functions produce **pseudo-random** numbers. Inputs like block time and block height make the output harder to guess, but the result is not truly random. In some contexts it could be predicted or manipulated. For security-critical randomness, get random data from an external oracle instead.

The full code for this guide is available in the [random number generation repository.](https://bitbucket.org/chromawallet/recipes/src/main/random-number-generation/)

The functions below rely on `op_context`, which you can only access inside operations. See the [op\_context reference](https://docs.chromia.com/rell/language-features/systemlib/namespaces/op_context) for details.

You can generate pseudo-random numbers in Rell with these functions:

* `get_random_number(high)`: Returns a number from 0 up to `high`, with both bounds inclusive. Block time, block height, and the operation index serve as sources of randomness.

  rell

  ```
  function get_random_number(high: integer = 100): integer {
      if (high == 0) return 0; // avoid division by zero
      return (op_context.last_block_time - op_context.block_height - op_context.op_index) % high + 1;
  }
  ```
* `get_random_number_in_range(from, to)`: Returns a number between `from` and `to`, with both bounds inclusive.

  rell

  ```
  function get_random_number_in_range(from: integer, to: integer): integer {
      require(from <= to, "To must be higher than from");
      return from + get_random_number(to - from);
  }
  ```
* `get_random_number_with_seed(high, seed)`: Takes an extra `seed` argument. When you need several random numbers in one operation, pass a different seed for each call, for example the loop iterator index. The function mixes a random hexadecimal number with block time, block height, and row ID. It reads the latest block data through the `block_dto` struct and the `get_last_block_data` function.

  rell

  ```
  function get_random_number_with_seed(high: integer, seed: integer = 0) {
      if (high == 0) return 0;
      val key = seed % 32;
      val last_block_data = get_last_block_data();
      val random_value = integer.from_hex(last_block_data.block_rid.to_hex()[key]) + (
          last_block_data.block_timestamp - last_block_data.block_height - last_block_data.rowid
      );
      return random_value % high + 1;
  }

  struct block_dto {
      timestamp;
      block_rid: byte_array;
      block_height: integer;
      rowid: integer;
  }

  function get_last_block_data(): (
      rowid: integer,
      block_height: integer,
      block_timestamp: integer,
      block_rid: byte_array
  ) {
      // Ensure the chain has at least 2 blocks written, as the last block may not have block_rid yet
    val blocks = block @* { .timestamp > 0 } (
        block_dto (
            timestamp = $.timestamp,
            block_rid = $.block_rid,
            block_height = $.block_height,
            rowid = $.rowid.to_integer()
        ),
        @omit @sort_desc $.timestamp
    ) limit 1;

    return when (blocks.size()) {
        1 -> (
            rowid = blocks[0].rowid,
            block_height = blocks[0].block_height,
            block_timestamp = blocks[0].timestamp,
            block_rid = blocks[0].block_rid
        );
        else -> (
            rowid = 88,
            block_height = 32253,
            block_timestamp = 55554444333,
            block_rid = chain_context.blockchain_rid
        );
    };
  }
  ```

These functions give your blockchain application pseudo-random numbers. Remember that pseudo-randomness has limits, and switch to a more secure source when you need true randomness.

Written for this site from Chromia’s public course. Code samples are the course’s own.

[← Course**Generating random numbers in Rell**](https://chromia.com/learn/random-number-generation/)[Course done →**Start building**](https://chromia.com/developers/#start)
