在C语言中生成一个32位的随机十六进制值

3

在C语言中生成一个随机的32位十六进制值,最好的方法是什么?在我的当前实现中,我是单独生成每一位二进制数,但输出结果并不完全随机......很多值会重复多次。生成整个随机数是否比单独生成每一位更好?

这个随机数应该利用整个32位地址空间(0x00000000至0xffffffff)。

file = fopen(tracefile,"wb"); // create file
for(numberofAddress = 0; numberofAddress<10000; numberofAddress++){ //create 10000 address
    if(numberofAddress!=0)
        fprintf(file,"\n"); //start a new line, but not on the first one

    fprintf(file, "0 ");
    int space;

    for(space = 0; space<8; space++){ //remove any 0 from the left
        hexa_address = rand() % 16;
        if(hexa_address != 0){
            fprintf(file,"%x", hexa_address);
            space++;
            break;
        }
        else if(hexa_address == 0 && space == 7){ //in condition of 00000000
            fprintf(file,"%x", "0");
            space++;
        }
    }

    for(space; space<8; space++){ //continue generating the remaining address
        hexa_address = rand() % 16;
        fprintf(file,"%x", hexa_address);
    }

}

你当前的代码生成的随机数与使用 rand 生成单个32位值一样随机。但是随机数会有重复的值。 - David Heffernan
2
为什么不直接调用一个随机数生成器呢?我忘了C的rand()函数是否返回64位数量(或完全随机的32位),但还有其他函数可以实现。而“十六进制”与32位数字有什么关系呢? - Hot Licks
上面的注释是基于 RAND_MAX 是最大整数的假设写的。 - David Heffernan
3个回答

14
x = rand() & 0xff;
x |= (rand() & 0xff) << 8;
x |= (rand() & 0xff) << 16;
x |= (rand() & 0xff) << 24;

return x;

rand() 并不能返回一个完整的随机32位整数。据我所知它返回的是 02^15 之间的值。(我认为这取决于具体实现)。因此,你需要多次调用并进行掩码处理。


4
它返回一个介于0到RAND_MAX之间的值。 - David Heffernan
@David Heffernan:正确,这只能保证至少为32767 - Mysticial
但是你提供的实现不会比萨钦更随机。虽然我同意它要好得多。 - David Heffernan
没错,你实际上只需要调用3次rand()就可以做到。但是移位计数和掩码会有所不同。 - Mysticial
那么x会是一个uint32_t数据类型吗? - j0h
如果您的随机数生成器只能提供15位结果,那么它很可能是基于15或16位RNG。然后,如果您取4个连续值,您将只得到2^16种可能的32位结果。如果您的RNG是随机种子的,那么在生成约300(2^8)个数字后,您很可能开始看到相同的32位数字。如果您让它运行,那么您将在2^14之后重复(因为您使用了4个RNG调用,而周期是4的倍数),或者在每次迭代时没有请求循环长度的除数时重复2^16。 - rew

0

这样做。它比之前的逻辑创建了一个更大的数字。如果您对 MSB 感兴趣,则下面的逻辑是不错的:

/** x = rand() ^ rand()<<1; **/

#include <algorithm>
#include <string.h>
#include <ctype.h>
#include <stdint.h>
#include <string>
#include <stdio.h>

int main () {
    int i, n;

    n = 50;
    uint x,y ;
    //4294967295 :UNIT_MAX
    /* Intializes random number generator */
    srand((unsigned) time(0));

    for( i = 0 ; i < n ; i++ ) {

        /**WAY 1 **/
        x = rand() ^ rand()<<1;

        printf("x:%u\t",x);
        printf("Difference1:(4294967295 - %u) = %u\n",x,(4294967295 - x));

        /**WAY 2 **/
        y  = rand() & 0xff;
        y |= (rand() & 0xff) << 8;
        y |= (rand() & 0xff) << 16;
        y |= (rand() & 0xff) << 24;
        printf("y:%u\t",y);
        printf("Difference2:(4294967295 - %u) = %u\n",y,(4294967295 - y));

        printf("Difference between two is = %u\n",(x) - (y));


    }
    printf("End\n");

    return(0);
}

-1

您可以创建任何至少32位宽的随机数,并将其格式化为十六进制。例如:

#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>

uint32_t n;

n = mrand48();    // #1
n = rand();       // #2

FILE * f = fopen("/dev/urandom", "rb");
fread(&n, sizeof(uint32_t), 1, f);  // #3

// ... etc. etc. E.g. Windows Crypto API

char hex[9];
sprintf(hex, "%08X", n);

现在,hex 是一个包含八个随机十六进制数字的字符串。不要忘记使用 srand48()srand() 来种子各种伪随机数生成器(分别用于 #1 和 #2)。由于你基本上需要使用至少一个32位整数从随机源中种子 PRNGs,所以最好直接从随机源获取(除非你使用 time() 或类似“非随机”的东西)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接