#include <iostream> #include <stdlib.h> #include <time.h> #iclude <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 ![]() srand 只调用一次不需要每次循环都重设 srand 。 如果需要真随机数或者用于加密学等用途请使用平台提供的 API 或者 STL 抽象出来的 std::random_device 。 但既然不支持 CPP11 ,那么你就只能选择使用平台提供的 API 了。 |
![]() | 3 AzadCypress 2023-02-06 00:44:27 +08:00 ![]() 因为 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 秒 |