Hasard API

Public Hasard API is the header file hasard.h.

Example

Example written in C language:

/**
 * "Hello World" example of Hasard library.
 * Show usage of common functions.
 *
 * Compile it using "gcc hello_world.c -lhasard -o hello_world".
 */

#include <hasard.h>
#include <stdio.h>

int main()
{
    struct hasard_t *rng;
    rng = hasard_new(HASARD_FAST);

    printf("Heads or Tails? %s!\n", hasard_bool(rng) ? "Heads" : "Tails");
    printf("Dice: %i\n", hasard_int(rng, 1, 6));
    printf("Integer in 0..999: %lu\n", hasard_ulong(rng, 0, 999));
    printf("Float in [0.0; 1.0(: %.3f\n", hasard_double(rng, 0.0, 1.0));

    hasard_destroy(rng);
    return 0;
}

Compile it with gcc example.c -o example -lhasard.

You don’t have to initialize the random generator seed like the common srand(time(NULL)): this task is done by hasard_new().

64-bit integers

HASARD_INT64 is defined if 64-bit integer are available. Otherwise, some functions like hasard_get_seed_uint64() are not available.

Initialization

To create the generator, you have two functions:

struct hasard_t* hasard_new(const char* profile)

Create a new hasard object: allocate memory and call the constructor. See the list of profiles for profile. Use hasard_new_full() to choose the engines at startup.

Return new allocated object on success, or NULL on error.

Example:

struct hasard_t* rng = hasard_new(HASARD_FAST);

See also hasard_set_error_callback(), hasard_setup_lock(), hasard_new_full() and hasard_destroy().

Changed in version 0.5: the function now has a profile parameter.

struct hasard_t* hasard_new_full(const char* rng_engine, const char* seed_engine)

Create a new hasard object: allocate memory and call the constructor:

Return new allocated object on success, and NULL on error.

See also hasard_set_error_callback(), hasard_setup_lock(), hasard_new() and hasard_destroy().

Example:

struct hasard_t* rng = hasard_new_full("arcfour", "@secure_blocking");

Functions return a new Hasard object on success, or NULL on error. Don’t forget to call hasard_destroy() at exit:

void hasard_destroy(struct hasard_t* rng)

Destroy a generator: free memory, unload libraries, close files, etc.

Clone a generator

struct hasard_t* hasard_clone(struct hasard_t *rng)

Clone the generator rng.

Return NULL if the generator can not be cloned

New in version 0.9.

Generate random numbers

bool hasard_bool(struct hasard_t* rng)

Generate a random boolean: true or false.

int hasard_int(struct hasard_t *rng, int min, int max)
int8_t hasard_int8(struct hasard_t*, int8_t min, int8_t max)
int16_t hasard_int16(struct hasard_t*, int16_t min, int16_t max)
int32_t hasard_int32(struct hasard_t*, int32_t min, int32_t max)

Generate a random signed integer in the range [min; max].

unsigned long hasard_ulong(struct hasard_t* rng, unsigned long min, unsigned long max)
uint8_t hasard_uint8(struct hasard_t* rng, uint8_t min, uint8_t max)
uint16_t hasard_uint16(struct hasard_t* rng, uint16_t min, uint16_t max)
uint32_t hasard_uint32(struct hasard_t* rng, uint32_t min, uint32_t max)

Generate a random unsigned integer in the range [min; max].

double hasard_double(struct hasard_t* rng, double min, double max)

Generate a random floating point number in the range [min; max(.

Changed in version 0.9: the function now generates a number in [min; max(, instead of [min; max].

Changed in version 0.4: the function now has min and max parameters.

Generate an array of random numbers

For best performances, use:

void hasard_ulong_array(struct hasard_t* rng, unsigned long *array, size_t size, unsigned long min, unsigned long max);

Generate size random unsigned numbers in the range [min; max].

void hasard_double_array(struct hasard_t* rng, double *array, size_t count, double min, double max);

Generate size random floating point numbers in the range [min; max(.

New in version 0.9.7.

Generate other kind of random values

void hasard_bytes(struct hasard_t* rng, void* dest, size_t size)

Generate size random bytes: write them into dest byte string.

Do nothing if size is 0.

int hasard_uuid(struct hasard_t* rng, char* uuid, size_t size)

Generate a random Universal Unique Identifier: UUID version 4. size must be at least 37 bytes (36 characters and the final null bytes).

Example of UUID: "3fd88720-a695-4254-ae0c-55a638368d73".

Return 1 on error, 0 on success.

Shuffle an array

void hasard_shuffle(struct hasard_t* rng, void *base, size_t count, size_t size)

Mix items in an array in a random order. Parameters:

  • base: address of the first item
  • count: number of elements
  • size: size of one element in bytes

Implement Fisher–Yates shuffle algorithm.

Do nothing if count is less than 2 or if size is zero.

Set generator direction

int hasard_set_forward(struct hasard_t *rng)

Set generator direction to forward.

Return 0 on success, or 1 on error.

New in version 1.5.

int hasard_set_backward(struct hasard_t *rng)

Set generator direction to backward.

Return 0 on success, or 1 on error (if the generator cannot run backward for example).

New in version 1.5.

Get and set the state of a generator

size_t hasard_get_state(struct hasard_t* rng, unsigned char** state)

Get a copy of the generator state.

Return 0 if it is not possible to get the state of the generator, for example it is an hardware generator.

Example:

size_t size;
unsigned char* state;

size = hasard_get_state(rng, &state);
int hasard_set_state(struct hasard_t* rng, const unsigned char* state, size_t size)

Restore the state of a generator.

Return 0 on success, 1 on error.

Warning

A state is NOT portable (depends on an integer size, of the endian, etc.) and can only be reused on the same computer. Use hasard_set_seed_xxx() functions (eg. hasard_set_seed_uint32()) to generate the same numbers on different computers.

Use hasard_clone() to clone a generator.

Get and set the seed

int hasard_reseed(struct hasard_t *rng)

Reseed the engine: regenerate the seed using the hasard seed engine. Return 0 on success, or 1 on error.

New in version 0.4.

To get current generator seed, you can use:

int hasard_get_seed_uint32(struct hasard_t* rng, uint32_t *seed)

Get the random number generator seed as an 32 bits unsigned integer.

Return 0 on success, or 1 on error.

New in version 0.5.

int hasard_get_seed_uint64(struct hasard_t* rng, uint64_t *seed)

Get the random number generator seed as an 64 bits unsigned integer.

Availability: need 64-bit integers.

New in version 0.5.

int hasard_set_seed_uint32(struct hasard_t* rng, uint32_t seed)

Set the random number generator seed from an 32 bits unsigned integer.

Return 0 on success, or 1 on error.

New in version 0.4.

int hasard_set_seed_uint64(struct hasard_t* rng, uint64_t seed)

Set the random number generator seed from an 64 bits unsigned integer.

Return 0 on success, or 1 on error.

Availability: need 64-bit integers.

New in version 0.5.

int hasard_set_seed_bytes(struct hasard_t* rng, const unsigned char* bytes, size_t size)

Set the random number generator seed from a bytes string.

Return 0 on success, or 1 on error.

New in version 0.5.

For some engines, it’s possible to set the seed but not to get it because the seed is only used to initialize the state and it’s not possible to retrieve the seed from the state. Get the state instead of getting the seed.

Get informations about the engines

Informations about the random number generator engine:

const char* hasard_rng_name(struct hasard_t* rng)

Get the name of the random number generator engine.

See the list of engines.

New in version 0.3.

const char* hasard_seed_name(struct hasard_t* rng)

Get the name of the seed engine.

See the list of engines.

New in version 0.3.

double hasard_min_period_log2(struct hasard_t* rng)

Base-2 logarithm of the minimum period of the generator.

Return a negative value (-1.0) if the maximum period is unknown.

double hasard_max_period_log2(struct hasard_t* rng)

Base-2 logarithm of the maximum period of the generator.

Return a negative value (-1.0) if the maximum period is unknown.

Low level functions

See the documentation of engine tick.

hasard_tick_t hasard_tick(struct hasard_t* rng)

Generate a random “tick”. A tick is the raw output of a generator: a random unsigned integer in range [0; tick_max]. Use hasard_tick_max() to get tick_max value.

hasard_tick_t hasard_tick_max(struct hasard_t* rng)

Get the maximum value of a tick: 0 for byte only generators.

unsigned int hasard_tick_bytes(struct hasard_t* rng)

Get the number of bytes generated by hasard_tick().

Return 0 if the engine has no tick callback or if hasard_tick_max() + 1 is not a power of 256.

New in version 0.9.

void hasard_tick_array(struct hasard_t* rng, hasard_tick_t *array, size_t size)

Generate count random “ticks”.

New in version 0.9.5.

int hasard_skip_ticks(struct hasard_t* rng, size_t count)

Skip the next count ticks.

Return 0 on success, or 1 on error.

New in version 0.7.

Changed in version 0.9: count type is now size_t, instead of unsigned long.

int hasard_skip_bytes(struct hasard_t* rng, size_t count)

Skip the next count bytes.

Return 0 on success, or 1 on error.

New in version 0.7.

Changed in version 0.9: count type is now size_t, instead of unsigned long.

Error handling

void (*hasard_error_prototype)(const char* message)

Error handler callback.

void hasard_set_error_callback(hasard_error_prototype display_error)

Set a custom error handler.

The default handler is hasard_display_error().

If display_error is NULL, ignore all errors.

void hasard_display_error(const char* message)

Display an error message.

void hasard_null_error(const char* message)

“Null” error handler: ignore all errors (do nothing).

Multithreading

If you want to share an Hasard object between multiple threads, you have to protect the internal state using locks.

int hasard_setup_lock(hasard_lock_new_prototype new_lock, hasard_lock_lock_prototype lock_lock, hasard_lock_unlock_prototype unlock_lock, hasard_lock_destroy_prototype destroy_lock)

Setup lock callbacks:

  • new: create a new mutex
  • lock: lock the mutex
  • unlock: unlock the mutex
  • destroy: destroy the mutex

This function must be called before the first call to hasard_new() or hasard_new_full().

Library version

const char* hasard_version_string(void)

Get the version of the Hasard library as a string. Example: 0.6.0.

unsigned int hasard_version(unsigned int* major, unsigned int *minor, unsigned int* revision)

Get the version of the Hasard library as an unsigned integer:

  • bits 16..23: major ((version >> 16) & 0xff)
  • bits 8..15: minor ((version >> 8) & 0xff)
  • bits 0..7: revision (version & 0xff)

If set, major, minor and/or revision are set to the major, minor and revision version.

int hasard_compare_version(unsigned int major, unsigned int minor, unsigned int revision)

Compare the version of the Hasard library with (major, minor, revision):

  • return negative number if the library is older
  • return zero if both versions are the same
  • return positive number if the library is newer

Example:

if (hasard_compare_version(0, 6, 0) < 0) {
    printf("Your Hasard version (%s) is older than 0.6, please upgrade!\n",
        hasard_version_string());
    exit(1);
}

Other functions

char* hasard_engine_list(void)

Get the list of available engines as a comma-separated string.

Return a new allocated string on success, or NULL on error (unable to allocate memory).

Example: randu,isaac,park_miller,windows,one.

char* hasard_profile_list(void)

Get the list of available profiles as a comma-separated string.

Return a new allocated string on success, or NULL on error (unable to allocate memory).

Example: @fast,@secure_nonblocking.