#include <iostream>
#include <stdlib.h>
#include <time.h>
#include <string>
using namespace std;
int main(int argc, char **argv)
{
string allcode = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz";
srand(time(NULL));
int l = 8; //指定的新字符串长度
string s; //新组成的随机字符串
char cc; //被抽中的字符
for (int i=0;i<l;i++)
{
srand(time(NULL));
int randNum = rand() % allcode.length();
cc = letters[randNum];
s = s + cc;
}
cout << s << endl;
// 为啥 s 是一串重复的字符串?
另外一个问题是,观察到 srand(time(NULL))的值是 1 秒内不会变的(在我用的电脑和系统上是这样),
如果一秒内有很多次循环,这个似乎不太好,应该如何更“真”的保证和上次循环有不同随机?
1
qazwsxkevin OP by the way ,原本是 python 做这个的,速度有些慢,所以临时找了大学时候的 Dev-C++绿色版搭配旧 GCC 3.4.2 版本,把 python 脚本转成 C++来完成这个事情,C++11 是没有的。。。
|
2
wevsty 2023-02-05 23:50:18 +08:00 1
srand 只调用一次不需要每次循环都重设 srand 。
如果需要真随机数或者用于加密学等用途请使用平台提供的 API 或者 STL 抽象出来的 std::random_device 。 但既然不支持 CPP11 ,那么你就只能选择使用平台提供的 API 了。 |
3
AzadCypress 2023-02-06 00:44:27 +08:00 1
因为 time(null)返回的是 从 1970 年到现在的 秒数 ,用同一个 seed 初始化的序列肯定是一样的
srand 一般只调用一次,把 for 循环里的 srand 删除就好了 |
4
qazwsxkevin OP 明白了,所以,
有啥办法,保证 1 秒内能拿 1 万个不同的种子呢? |
5
cnbatch 2023-02-06 03:18:22 +08:00
最佳做法就是换新的编译器( MSVC 或者 GCC 或者 Clang 均可),使用 C++11 的 std::random_device
(等待答案的这段时间,足够用来下载新版本了) cppreference 连示例都列出来了 https://en.cppreference.com/w/cpp/numeric/random/random_device/random_device 照抄就能用,只需要按照实际需求改一改 d(0, 9) 的范围就可以了 顺便扩充点内容: cppreference 给出的这段 demo 用了 4 种不同的 std::random_device 初始化版本,对于 MSVC 而言全都一样,初始化参数会自动忽略掉(我猜也许 GCC 和 Clang 在 Windows 都是一样的,若要确定那就需要查源码,我懒得查了),微软自己的文档就有提到‘the values produced are non-deterministic and cryptographically secure, but runs more slowly than generators created from engines and engine adaptors’ https://learn.microsoft.com/en-us/cpp/standard-library/random-device-class?view=msvc-170 似乎在暗示 MSVC 的 std::random_device 会尽可能调用硬件生成器 |
6
piku 2023-02-06 09:14:47 +08:00 via Android
Python 慢?试了一万行 8 随机字母只有 0.128 秒
|