简体   繁体   English

C中如何生成12位随机数?

[英]How to generate 12 digit random number in C?

I'm trying to generate 12 digit random numbers in C, but it's always generating 10 digit numbers.我试图在 C 中生成 12 位随机数,但它总是生成 10 位数字。

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

void main()
{
   srand(time(NULL));
   long r = rand();
   r = r*100;
   printf("%ld",r);
}

rand() returns an int value in the range of [0...RAND_MAX] rand()返回int值,范围为[0...RAND_MAX]

Based on the C spec, RAND_MAX >= 32767 and RAND_MAX <= INT_MAX . 基于C规范, RAND_MAX >= 32767RAND_MAX <= INT_MAX

Call rand() multiple times to create a wide value 多次调用rand()以创建一个广泛的价值


unsigned long long rand_atleast12digit(void) {
  unsigned long long r = rand();
  #if RAND_MAX >= 999999999999
  #elif RAND_MAX >= 999999
    r *= RAND_MAX + 1ull;
    r += rand();
  #else
    r *= RAND_MAX + 1ull;
    r += rand();
    r *= RAND_MAX + 1ull;
    r += rand();
  #endif
  return r;
}

The above returns a number if the range of 0 to at least 999,999,999,999. 如果介于0到至少 999,999,999,999之间,则上面的代码返回一个数字。 To reduce that to only that range, code could use return r % 1000000000000; 为了将其减小到该范围,代码可以使用return r % 1000000000000; .


Using % likely does not create an balanced distribution of random numbers. 使用%可能不会创建随机数的平衡分配。 Other posts address details of how to cope with that like this good one incorporated as follows. 其他帖子详细介绍了如何应对这种情况 ,如下所示。

#if RAND_MAX >= 999999999999
  #define R12DIGIT_DIVISOR (RAND_MAX/1000000000000)
#elif RAND_MAX >= 999999
  #define RAND_MAX_P1  (RAND_MAX+1LLU)
  #define R12DIGIT_DIVISOR ((RAND_MAX_P1*RAND_MAX_P1-1)/1000000000000)
#else
  #define RAND_MAX_P1  (RAND_MAX+1LLU)
  #define R12DIGIT_DIVISOR  ((RAND_MAX_P1*RAND_MAX_P1*RAND_MAX_P1-1)/1000000000000)
#endif

unsigned long long rand_12digit(void) {
    unsigned long long retval;
    do { 
        retval = rand_atleast12digit() / R12DIGIT_DIVISOR;
    } while (retval == 1000000000000);
    return retval;
}

Note that the quality of rand() is not well defined, so repeated calls may not provide high quality results. 请注意, rand()的质量定义不明确,因此重复调用可能无法提供高质量的结果。


OP's code fails if long is 32-bit as it lacks range for a 12 decimal digit values. 如果long为32位,则OP的代码将失败,因为它缺少12位十进制数字值的范围。 @Michael Walz @迈克尔·沃尔兹

If long is wide enough, *100 will always make the least 2 decimal digits 00 - not very random. 如果long足够宽, *100将始终使至少2个十进制数字00不是很随机。 @Alexei Levenkov @亚历克谢·莱文科夫

long r = rand();
r = r*100;

The result of rand is int , which means you can't get a 12 digit number directly from it. rand的结果int ,这意味着您不能直接从中获取12位数字。

If you need value that is always 12 digits you need to make sure values fit in particular range. 如果需要始终为12位数字的值,则需要确保值适合特定范围。

Sample below assumes that you need just some of the numbers to be 12 digits - you just need 8 extra bits - so shifting and OR'ing results would produce number in 0x7fffffffff-0 range that would often result up to 12 digit output when printed as decimal: 下面的示例假定您只需要一些数字为12位-您只需要8个额外的位-因此移位和运算结果将产生0x7fffffffff-0范围内的数字,当打印为时,通常会产生多达12位的输出十进制:

r = rand();
r = (r << 8) | rand();

PS: Make sure the variable that will store the result is big enough to store the 12 digit number. PS:确保将用于存储结果的变量足够大以存储12位数字。

My simple way to generate random strings or numbers is:我生成随机字符串或数字的简单方法是:

static char *ws_generate_token(size_t length) {

    static char charset[] = "abcdefghijklmnopqrstuvwxyz1234567890";
    char *randomString = NULL;

    if (length) {
        randomString = malloc(sizeof(char) * (length + 1));

        if (randomString) {
            for (int n = 0; n < length; n++) {
                int key = rand() % (int)(sizeof(charset) -1);
                randomString[n] = charset[key];
            }

            randomString[length] = '\0';
        }
    }

    return randomString;
}

Explain the code解释代码

  1. Create an array of chars which will contains (numbers, alphabets...etc)创建一个包含(数字,字母等)的字符数组
  2. Generate a random number between [0, array length], let's name it X.生成一个介于[0,数组长度]之间的随机数,我们命名为X。
  3. Get the character at random X position in the array of chars.在字符数组中随机获取字符 X position。
  4. finally, add this character to the sequence of strings (or numbers) you want to have in return.最后,将此字符添加到您希望返回的字符串(或数字)序列中。

How to use it?如何使用它?

#define TOKEN_LENGTH      12
char *token;

token = ws_generate_token(TOKEN_LENGTH);

conversion from string to int从字符串到整数的转换

int token_int = atol(token);

dont forget !别忘了!

free(token); // free the memory when you finish
    #include <stdio.h>
#include <stdlib.h>

int main()
{
   int i, n;
   time_t t;

   n = 5;

   /* Intializes random number generator int range */
   srand((unsigned) time(&t));

   /* Print 5 random numbers from 50 to back
   for( i = 0 ; i < n ; i++ ) 
   {
      printf("%d\n", rand() % 50);
   }

   return(0);
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM