快速随机字符串

路易斯·艾蒂安

我正在尝试为程序生成随机字符串ID(该ID仅在程序执行期间必须是唯一的)。我首先在Python中完成了它,没有任何问题:

class RandomIdGenerator:
    _base_62_chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"

    @classmethod
    def get_base_62(cls, length):
        return "".join([random.choice(RandomIdGenerator._base_62_chars) for _ in range(length)])

但是由于我需要程序使用C ++,所以我试图用它生成相同的字符串。这就是我现在要做的:

void Node::setId()
{
    QString allow_symbols("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
    qsrand(QTime::currentTime().msec());

    for (int i = 0; i < ID_LENGTH; ++i) {
        id_.append(allow_symbols.at(qrand() % (allow_symbols.length())));
    }
}

我有两个主要问题。首先,它不使用C ++ 11(我不知道Qt的工作原理,但我不认为它是C ++ 11),并且生成的ID都相同。如果生成其中四个,则得到:

"R4NDM1xM"
"R4NDM1xM"
"R4NDM1xM"
"R4NDM1xM"

我尝试使用C ++ 11方法,但得到的结果相同,甚至更糟,在每次执行时,我得到的结果完全相同:

void Node::setId()
{
    id_ = "";

    const std::string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    std::random_device rd;
    std::mt19937 generator(rd());
    std::uniform_int_distribution<int> dist(0, str.size() - 1);

    for (int i = 0; i < Node::ID_LENGTH; ++i)
        id_ += str[dist(generator)];
}

如何在每次调用方法时生成随机字符串ID?

内森·奥利弗

除非您需要再次重复一个“随机”序列,否则随机数生成器只能播种一次。这意味着qsrand(QTime::currentTime().msec());只能在您第一次输入时调用setId()这有点棘手,因为它是一个函数调用,但是您可以添加一个静态bool变量来跟踪它是否已经运行,如果已经运行,则不要再次调用它。就像是

void Node::setId()
{
    static bool seeded = false;
    QString allow_symbols("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789");
    if (!seeded) 
    {
        qsrand(QTime::currentTime().msec());
        seeded = true;
    }

    for (int i = 0; i < ID_LENGTH; ++i) {
        id_.append(allow_symbols.at(qrand() % (allow_symbols.length())));
    }
}

C ++ 11代码甚至更容易。由于随机数生成器是一个对象,您可以使其成为静态对象,并且仅在首次调用该函数时才将其初始化。这意味着您的代码将变为:

void Node::setId()
{
    id_ = "";
    id_.reserve(Node::ID_LENGTH); // preallocate storage

    static const std::string str = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

    static std::random_device rd;
    static std::mt19937 generator(rd());
    static std::uniform_int_distribution<int> dist(0, str.size() - 1);

    for (int i = 0; i < Node::ID_LENGTH; ++i)
        id_ += str[dist(generator)];
}

还应注意,std::random_device它由不确定性来源提供支持。如果您的实现不支持该实现,则可能是std::random_device每次调用它都产生相同的序列。如果是这种情况,那么您将不得不使用其他选项进行播种,generator例如使用当前时间。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章