一、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表示要生成多少行字符。