c++ - 在 C++ 中生成随机字符串的最有效方法是什么?

标签 c++ string random c++17

我需要高效地生成随机字符串。在下文中,您将看到我的第一次尝试。我用 gcc 和 -O3 优化级别编译了代码。生成 10^7 个长度为 64 的随机字符串需要 18.5 秒:

#include <iostream>
#include <random>
#include <algorithm>

std::string chars {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()`~-_=+[{]{|;:'\",<.>/?"};
std::random_device rd;
std::mt19937 generator(rd());
  
std::string rand_str (int length) {
  std::string output (chars);
  std::shuffle(output.begin(), output.end(), generator);
  return output.substr(0, length);
}

int main() {
  std::string str;
  for (long i=0; i<10000000; ++i)
      str = rand_str (64);
}

我检查了 c++17 中的 std::sample,它并不比上述方法快。此外,它不会改变字符的顺序,因此不是真正的随机。

编辑 std::shuffle 不是一个好的选择,因为它不允许重复。根据评论我修改了代码。这次 10^7 个随机数需要 9 分钟

std::string rand_str (size_t length) {
  const size_t char_size = chars.size();
  std::uniform_int_distribution<> random_int (0, char_size - 1);
  std::string output;
  for (size_t i=0; i<length; ++i)
    output.push_back(chars[random_int(generator)]);
  return output;
}

问题

  • 在现代 C++ 中是否有更有效的方法来做到这一点?

我感谢任何改进代码的建议。

最佳答案

#include <iostream>
#include <random>
#include <algorithm>
#include <chrono>

std::string chars {"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890!@#$%^&*()`~-_=+[{]{|;:'\",<.>/?"};
std::random_device rd;
std::mt19937 generator(rd());
  
std::string rand_str(int length) {
  std::string output;
  output.reserve(length);

  while(length>0)
  {
      auto randNumb = generator();
      while(randNumb > 93 && length--)
      {
        output.push_back(chars[randNumb%93]);
        randNumb/=93;
      }
  }
  return output;
}

int main() {
  auto startTP = std::chrono::system_clock::now();
  std::string rand_bytes;
  for (long i=0; i<10000000; ++i)
      rand_bytes = std::move(rand_str(64));
  auto endTP = std::chrono::system_clock::now();

  std::cout << "This took: " << std::chrono::duration_cast<std::chrono::microseconds>(endTP-startTP).count() << std::endl;
}

这在我的机器上大约需要 3 秒。诀窍是尽可能少地调用随机数生成器,并且只分配一次内存。

我正在做的是将 randNumber 从 base 10 转换为 base 93(字符的长度)。之后,我将每个 93 位基数用作不同的随机数。这为每个生成的随机数提供了大约 5 个数字。

关于c++ - 在 C++ 中生成随机字符串的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63358009/

相关文章:

android - iOS和Android通用随机数生成器

javascript - 我怎样才能制作一个没有重复的随机数组?

c++ - Opencv train cascade 卡住,命中率为 1,误报率为 0

python - 使用 Python 修复 HTML 字符串中的开括号问题

c++ - 使用 SCons 构建外部代码树

python - 获取字符串的字符(从右到右)

Android - 在 XML(字符串数组)文件中搜索项目

c++ - 最快的加密安全随机数生成器

c++ - std::enable_if 类型检查

c++ - crtdbg 在使用 sf::Text::setOutlineThickness 时转储内存泄漏