Linux C伪随机数编程

一、rand产生伪随机数

Linux中rand()会返回一随机数值,范围在0至RAND_MAX 间,其中RAND_MAX定义在stdlib.h,其值为2147483647。
 例一:

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

#define LOOP_TIMES    10

int main(int argc, char *argv[])

{

int i;

for(i=0; i< LOOP_TIMES; i++)

printf("%d ", rand());

printf("\n");

return 0;

}
运行结果:

$ ./rand
1804289383 846930886 1681692777 1714636915 1957747793 424238335 719885386 1649760492 596516649 1189641421

$ ./rand
1804289383 846930886 1681692777 1714636915 1957747793 424238335 719885386 1649760492 596516649 1189641421
从以上的结果可以看出,rand两次产生的随机数是一样的,之所以这样是因为“在调用rand函数产生随机数前没有先利用srand()设好随机数种子”。如果未设随机数种子,rand()在调用时会自动设随机数种子为1。

二、srand设置随机数种子

要想每次运行得到的随机数不同,我们还要设置随机数种子。既然要设置随机数种子,那我们就使用srand()来设置rand()产生随机数时的随机数种子。参数seed必须是个整数,通常可以利用geypid()或time(NULL)的返回值来当做seed。如果每次seed都设相同值,rand()所产生的随机数值每次就会一样。
 例二:

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

#include <time.h>

#define LOOP_TIMES    10

int main(int argc, char *argv[])

{

int i;

srand((unsigned int) time(NULL));

for(i=0; i<LOOP_TIMES; i++)

printf("%d ", rand());

printf("\n");

return 0;

}

运行结果:

$ ./rand
1943306114 679448932 319436844 1922998560 1458181616 1014851378 1974968086 1165786630 1018064189 616343319

$ ./rand
1789418334 999331839 757991171 363979956 882919632 1822202571 764206645 468470327 402899724 1322937764

三、合理利用随机数

运行结果是不是不同了,但这么大的数对我们来说也没有多大意义,又怎么利用这些这些随机数呢?我们可对它进行范围化分,这样就可以产生我们想要范围内的数。
 产生一定范围随机数的通用表示公式:
    要取得[a,b)的随机整数,使用(rand() % (b-a))+ a;
    要取得[a,b]的随机整数,使用(rand() % (b-a+1))+ a,另一种表示为a + (int)b * rand() / (RAND_MAX + 1);
    要取得(a,b]的随机整数,使用(rand() % (b-a))+ a + 1;
    通用公式:a + rand() % n;其中的a是起始值,n是整数的范围;
    要取得0~1之间的浮点数,可以使用rand() / double(RAND_MAX)。

例三:

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

#include <time.h>

#define LOOP_TIMES    10

int main(int argc, char *argv[])

{

int i, nu;

srand((unsigned int) time(NULL));

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

nu = 0 + (int)( 26.0 *rand()/(RAND_MAX + 1.0));

printf("%d ", nu);

}

printf("\n");

return 0;

}
运行结果:

$ ./rand
6 21 20 22 7 18 2 21 14 3
$ ./rand
4 12 25 3 13 2 0 0 20 12

这个例子主要是生成[0,26]之间的数,使用了语句“nu = 0 + (int)( 26.0 *rand()/(RAND_MAX + 1.0));”来获取a到b之间的随机整数。

四、生成随机字符串

例四:

#include <stdlib.h>
 
#include <string.h>

#include <stdio.h>

#include <time.h>

#define BUFFER_LENGTH 257

int main(int argc, char *argv[])

{

int leng = 128 ;

int i, nu;

char buffer[BUFFER_LENGTH];

printf("Please Input length for the String, Default is 128, The Maxest legth is 256:");

fgets(buffer, BUFFER_LENGTH, stdin);

buffer[strlen(buffer)-1] = '\0' ;

if(buffer[0] != '\0')

leng = atoi(buffer);

srand((unsigned int)time(NULL));

bzero(buffer, BUFFER_LENGTH);

for (i= 0; i< leng; i++)

buffer[i] = 'a' + ( 0+ (int)(26.0 *rand()/(RAND_MAX + 1.0)));

buffer[strlen(buffer)] = '\0';

printf("The randm String is [ %s ]\n", buffer);

return 0;

}
运行结果:

$ ./rand
Please Input length for the String, Default is 128, The Maxest legth is 256:8
The randm String is [ rdekbnxj ]
$ ./rand
Please Input length for the String, Default is 128, The Maxest legth is 256:36
The randm String is [ bvfrbvvhdcuwdoarefcrkytsntltawpbsusu ]
注意,需要使用“bzero(buffer, 257);”这条语句将缓存清空,否则生成的随机字符串中可能就会出现乱码的情况。

五、shell指令生成字符串

生成全字符随机的字串:

cat /dev/urandom | strings -n C | head -n L
生成数字加字母的随机字串:

cat /dev/urandom | sed 's/[^a-zA-Z0-9]//g' | strings -n C | head -n L
其中C表示字符串的字符数,L表示要生成多少行字符。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/76ccb305a831968a296aa9c705a0f164.html