【问题标题】:C++: Generate unique string in a program launched several times at the same secondC ++:在同一秒启动多次的程序中生成唯一字符串
【发布时间】:2014-07-10 04:58:03
【问题描述】:

我有一个工具,每次启动时都需要创建一个唯一的目录。

此工具可以同时启动多次

当我使用常规的 srand(time(NULL))rand() 时,如果我的工具在同一秒内多次启动,我会得到相同的“唯一”字符串。

这是我的问题的一个例子:

$ ./rand_string.exe
9IQMT8F63P37G3LO4O85LM1LRTEBTV3Q1DOX3B46SAUYUBPYKDMZER9M8DAZSVPT

$ ./rand_string.exe
I01QZ47I0FV3WCW597NLE3M9B75Q5S5ADFB23T4OZR0W2VM2E91XJYHWGGVMEAE0

# Time is still the same, getting same "unique" string
$ ./rand_string.exe
I01QZ47I0FV3WCW597NLE3M9B75Q5S5ADFB23T4OZR0W2VM2E91XJYHWGGVMEAE0

# Time is still the same, getting same "unique" string
$ ./rand_string.exe
I01QZ47I0FV3WCW597NLE3M9B75Q5S5ADFB23T4OZR0W2VM2E91XJYHWGGVMEAE0

$ ./rand_string.exe
LWNXWSTODGGC8B46JB0ZII950LJOPJ8EG3GEI885U58CLXHA3L0DBCXIX6I0I2SZ

$ ./rand_string.exe
UUY1245J9RO8O1G6OVEYBZUTK0PNGG9ER52JIQSN1MEUDGZEXHFBHJ6R6TJ74H1Q

$ ./rand_string.exe
3SP49GYF6HG4KAS7UVTELWWG4FW28UAY384PI8CLP3ZS50WIRXFTMQEKEWKE6DQY

# Time is still the same, getting same "unique" string
$ ./rand_string.exe
3SP49GYF6HG4KAS7UVTELWWG4FW28UAY384PI8CLP3ZS50WIRXFTMQEKEWKE6DQY

这是我的代码(只是为了让“随机”实现有意义):

#include <cstdlib>
#include <ctime>
#include <iostream>

void cpy_rand_str(char *dest, int size) {
        int i;
        int rand_num;

        srand (time(NULL));

        for (i = 0 ; i < size ; i++) {
                rand_num = rand() % 36;
                if (rand_num >= 10) {
                        rand_num += ('A' - 10);
                } else {
                        rand_num += '0';
                }
                dest[i] = (char)rand_num;
        }
        dest[size] = '\0';
}


int main() {
        char my_key[64 + 1];

        cpy_rand_str(my_key, 64);
        std::cout << my_key << "\n";

        return 0;
}

【问题讨论】:

  • 因为srand 就是这样工作的。调用它将为生成的随机数设置种子。而种子取决于时间,到秒。所以每秒调用几次会产生相同的“随机”字符串。
  • 混合一些独特的东西,比如 PID,或者带有更高分辨率计数器的种子。
  • @user3322273 如果允许 C++11,您也可以在 &lt;random&gt; 标头中查看解决方案。
  • @Theolodis,还有多少兰特?如果我用 srand() 对它进行 rand 它,我每次都会得到相同的“额外 rand” :)
  • 如您所见,srand只适用于一次性玩具;不适合任何严肃的应用

标签: c++ random uuid


【解决方案1】:

这几乎就是 tmpnam 旨在完成的任务。它并不完美(例如,它对竞争条件开放)但至少有一定的工作机会,对于大多数明显的替代方案来说,这比你可以说的要多。作为奖励,它生成的字符串专门用于符合主机作为文件名的要求,这通常意味着它可以用作目录的名称。

【讨论】:

  • 您提供的链接在错误下显示“永远不要使用此功能。请改用 mkstemp(3) 或 tmpfile(3)。”这两个分别返回文件描述符的FILE*int,因此它们有望用于OP。
  • mkdtemp 如果可用,可能是更好的选择。
  • @Namfuak:它们都创建文件,而不是他要求的目录。 mkdtemp 应该可以工作,但我不愿推荐它,因为可用性相当有限。 tmpnam 的缺点有些夸大其词——如果使用不当可能会出现问题,但只要小心谨慎,大多数此类问题都可以避免。 OTOH,如果您依赖它来确保安全,那可能是一个真正的问题。
  • 看起来 mkdtemp() 是我的情况的正确解决方案
【解决方案2】:

您可以使用实际的UUIDs 和boost,例如:

boost::uuids::basic_random_generator<boost::mt19937> gen;
boost::uuids::uuid u = gen(); //generate uuid

std::string s1 = to_string(u);

这将是独立于平台的,并且有一个非常 low probability 用于碰撞。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-20
    • 1970-01-01
    • 2013-10-07
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    • 2011-09-24
    相关资源
    最近更新 更多