c语言随机数rand,C语言rand()获取随机数和windows下的CryptGenRandom

是在弄即将发布的一篇博客时顺便弄的,还是先写这个。

rand()函数已经被说烂了,包括这里写的,返回一个0到RAND_MAX(在我的电脑上是32767)的整数。srand(unsigned int)可以设置随机种子,默认为1。设定了初始的随机种子后,以后再重复调用rand()所生成的随机数是确定的。

代码如下

#include

#include

#include

int main() {

int i;

printf("%d\n\n", RAND_MAX);

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

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

puts("");

srand(1);

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

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

puts("");

srand(time(NULL));

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

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

puts("");

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

srand(time(NULL));

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

}

return 0;

}

运行结果:

32767

41 18467 6334 26500 19169 15724 11478 29358 26962 24464

41 18467 6334 26500 19169 15724 11478 29358 26962 24464

23940 10437 3649 15425 14939 32113 15093 28994 14396 16990

23940 23940 23940 23940 23940 23940 23940 23940 23940 23940

第一行是还没有设置随机种子的结果,与第二行将随机种子设置为1后的结果完全相同。第三行是正常情况,第四行是我曾经犯过的一个错误(所以才有了这篇博客),由于time()函数返回的是从1970.1.1 0:00起到调用时经过的秒数,而两次调用之间的时间间隔又很短,所以每次都设置了相同的随机种子,生成的随机数也因此完全相同。此外我还试过用clock()函数的返回值(程序启动开始经过的毫秒数)作为随机种子,后来想想还是不太好,毕竟这个返回值可能会比较有规律,而且通常取值范围较小,而time()的返回值可以保证基本不会重复(除非把unsigned int溢出了……)。

当然本身rand()函数就不是太靠谱,我又想起了之前一篇讲加盐哈希的文章里面提到过的windows下提供的很多语言都可以使用的CryptGenRandom函数,于是从官网复制了下来试了一下,虽然写着C++但是C语言也可以运行,不过懒得仔细看,能用就算了……

#include

#include

#include

int main() {

int a = 0;

HCRYPTPROV Rnd;

LPCSTR UserName = "MyKeyContainer";

if(CryptAcquireContext(&Rnd, UserName, NULL, PROV_RSA_FULL, 0)) {

printf("A cryptographic context with the %s key container ",

UserName);

printf("has been acquired.\n\n");

} else {

if (GetLastError() == NTE_BAD_KEYSET) {

if(CryptAcquireContext(

&Rnd,

UserName,

NULL,

PROV_RSA_FULL,

CRYPT_NEWKEYSET)) {

printf("A new key container has been created.\n");

} else {

printf("Could not create a new key container.\n");

exit(1);

}

} else {

printf("A cryptographic service handle could not be "

"acquired.\n");

exit(1);

}

}

if (CryptGenRandom(Rnd, 4, (BYTE*)(&a)))

printf("%d\n\n", a);

else

puts("failed\n");

if (CryptReleaseContext(Rnd,0)) {

printf("The handle has been released.\n\n");

} else {

printf("The handle could not be released.\n\n");

}

return 0;

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值