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

问题描述

我需要高效地生成随机字符串。在下面,您将看到我的第一次尝试。我用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从10转换为93(字符的长度)。之后,我使用每个基本的93位数字作为不同的随机数。每个生成的随机数大约提供5个数字。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...