1. ホーム
  2. c

[解決済み] C言語で/dev/randomやurandomを使用するには?

2023-06-13 10:04:55

質問

私は /dev/random または /dev/urandom をCで処理するにはどうしたらいいのでしょうか?C言語でどのように処理すればいいのかわかりません。もし知っている人がいれば教えてください。ありがとうございます。

どのように解決するのですか?

一般に、ランダムなデータを取得するためにファイルを開くことは避けたほうがよいでしょう。

最近のLinuxディストリビューションでは getrandom システムコールを使って暗号化された乱数を取得することができ、失敗することはありません。 もし GRND_RANDOM ではない がフラグとして指定されておらず、読み出し量が最大256バイトであること。

2017年10月現在、OpenBSD、Darwin、Linux(で -lbsd ) の実装をすべて持つようになりました。 arc4random を実装することができるようになりました。そのため、非常に魅力的な選択肢となっています。

char myRandomData[50];
arc4random_buf(myRandomData, sizeof myRandomData); // done!

そうでなければ、ランダムデバイスをファイルのように使用することができます。そこから読み込むと、ランダムなデータが得られます。私が使っている open / read ここで、しかし fopen / fread も同じように動作します。

int randomData = open("/dev/urandom", O_RDONLY);
if (randomData < 0)
{
    // something went wrong
}
else
{
    char myRandomData[50];
    ssize_t result = read(randomData, myRandomData, sizeof myRandomData);
    if (result < 0)
    {
        // something went wrong
    }
}

ファイルディスクリプタを閉じる前に、さらに多くのランダムバイトを読み込むことができます。システムコールがシグナルによって中断されない限り、/dev/urandom は決してブロックせず、常に要求されただけのバイトを埋めます。これは暗号学的に安全であると考えられており、あなたが使用するランダムデバイスであるべきです。

/dev/random はより繊細です。ほとんどのプラットフォームでは、要求されたよりも少ないバイト数で返すことができ、十分なバイト数がない場合はブロックされることがあります。これは、エラー処理をより複雑にしています。

int randomData = open("/dev/random", O_RDONLY);
if (randomData < 0)
{
    // something went wrong
}
else
{
    char myRandomData[50];
    size_t randomDataLen = 0;
    while (randomDataLen < sizeof myRandomData)
    {
        ssize_t result = read(randomData, myRandomData + randomDataLen, (sizeof myRandomData) - randomDataLen);
        if (result < 0)
        {
            // something went wrong
        }
        randomDataLen += result;
    }
    close(randomData);
}