【问题标题】:Generating a random 32 bit hexadecimal value in C在 C 中生成随机的 32 位十六进制值
【发布时间】:2011-10-01 20:49:46
【问题描述】:

在 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 位值一样随机。随机数具有重复值。
  • 为什么不直接调用随机数生成器呢?我忘记了 C 的 rand() 是否返回 64 位数量(或完全随机的 32 位),但还有其他的。而“十六进制”与 32 位数字有什么关系?
  • 上面的评论假设 RAND_MAX 是最大 int

标签: c random hex


【解决方案1】:
x = rand() & 0xff;
x |= (rand() & 0xff) << 8;
x |= (rand() & 0xff) << 16;
x |= (rand() & 0xff) << 24;

return x;

rand() 不返回完全随机的 32 位整数。上次我检查它在0 和2^15 之间返回。 (我认为它依赖于实现。)所以你必须多次调用它并屏蔽它。

【讨论】:

  • 返回 0 到 RAND_MAX 范围内的值
  • @David Heffernan:正确,仅保证至少为32767。
  • 但是你给出的实现不会比 Sachin 的更随机。虽然我同意它要好得多。
  • 没错,您实际上只需调用 3 次 rand() 即可。但班次计数和掩码会有所不同。
  • 那么 x 会是 uint32_t 数据类型吗?
【解决方案2】:

这样做。它创建的数字比之前的逻辑更大。如果您对 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);
}

【讨论】:

    【解决方案3】:

    您可以创建 any 至少 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 位整数从随机源播种 PRNG,因此您不妨直接点击随机源(除非您使用 time() 或类似的“非随机”) .

    【讨论】:

      猜你喜欢
      • 2010-11-06
      • 1970-01-01
      • 1970-01-01
      • 2018-11-27
      • 2014-07-03
      • 2016-02-04
      • 2018-06-07
      • 2012-12-09
      • 1970-01-01
      相关资源
      最近更新 更多