Cでランダムなintを生成するには?

#include <time.h>
#include <stdlib.h>

srand(time(NULL));   // Initialization, should only be called once.
int r = rand();      // Returns a pseudo-random integer between 0 and RAND_MAX.

Linux では、random と srandom を使用することをお勧めします。


rand() <stdlib.h> の関数 0 から RAND_MAX までの擬似乱数整数を返します . srand(unsigned int seed) を使用できます 種を設定します。

% を使用するのが一般的です。 rand() と組み合わせた演算子 異なる範囲を取得します(ただし、これにより均一性が多少失われることに注意してください)。例:

/* random int between 0 and 19 */
int r = rand() % 20;

あなたが本当に 均一性に気を配ると、次のようなことができます:

/* Returns an integer in the range [0, n).
 *
 * Uses rand(), and so is affected-by/affects the same seed.
 */
int randint(int n) {
  if ((n - 1) == RAND_MAX) {
    return rand();
  } else {
    // Supporting larger values for n would requires an even more
    // elaborate implementation that combines multiple calls to rand()
    assert (n <= RAND_MAX)

    // Chop off all of the values that would cause skew...
    int end = RAND_MAX / n; // truncate skew
    assert (end > 0);
    end *= n;

    // ... and ignore results from rand() that fall above that limit.
    // (Worst case the loop condition should succeed 50% of the time,
    // so we can expect to bail out of this loop pretty quickly.)
    int r;
    while ((r = rand()) >= end);

    return r % n;
  }
}

安全なランダム文字または整数が必要な場合:

さまざまなプログラミング言語で乱数を安全に生成する方法で説明されているように、次のいずれかを実行する必要があります:

  • libsodium の randombytes を使用 API
  • libsodium の sysrandom 実装から必要なものを、非常に慎重に再実装してください
  • より広く、/dev/urandom を使用します 、 /dev/random ではありません . OpenSSL (または他のユーザー空間 PRNG) ではありません。

例:

#include "sodium.h"

int foo()
{
    char myString[32];
    uint32_t myInt;

    if (sodium_init() < 0) {
        /* panic! the library couldn't be initialized, it is not safe to use */
        return 1; 
    }


    /* myString will be an array of 32 random bytes, not null-terminated */        
    randombytes_buf(myString, 32);

    /* myInt will be a random number between 0 and 9 */
    myInt = randombytes_uniform(10);
}

randombytes_uniform() 暗号学的に安全で、公平です。