[英]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.