[英]Fast random string
我正在尝试为程序生成随机字符串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
提供种子,例如使用当前时间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.