Merge pull request #2575 from unxed/wiki_help
[far2l.git] / utils / src / RandomString.cpp
blobbdcbbaec4de4aad30504e961b9419f928433178d
1 #include <random>
2 #include <time.h>
3 #include <unistd.h>
4 #include <stdlib.h>
5 #include <atomic>
6 #include "BitTwiddle.hpp"
7 #include "RandomString.h"
9 static std::atomic<uint32_t> s_rnd_next_seed;
11 size_t RandomStringBuffer(unsigned char *out, size_t min_len, size_t max_len, unsigned int flags)
13 std::mt19937 rng;
14 rng.seed(getpid() ^ time(NULL) ^ RevBytes(uint32_t(clock())) ^ uint32_t(s_rnd_next_seed));
15 size_t len = min_len;
16 if (max_len > min_len) {
17 std::uniform_int_distribution<std::mt19937::result_type> len_dist(0, max_len - min_len);
18 len+= len_dist(rng);
21 std::uniform_int_distribution<std::mt19937::result_type> chr_dist(0, 0xff);
22 for (size_t i = 0; i < len; ) {
23 unsigned char v = chr_dist(rng);
24 if (v == 0) {
25 if ((flags & RNDF_ZERO) == 0) {
26 continue;
28 } else if (v >= 'A' && v <= 'Z') {
29 if ((flags & RNDF_HICASE) == 0) {
30 continue;
32 } else if (v >= 'a' && v <= 'z') {
33 if ((flags & RNDF_LOCASE) == 0) {
34 continue;
36 } else if (v >= '0' && v <= '9') {
37 if ((flags & RNDF_DIGITS) == 0) {
38 continue;
40 } else if (v >= 128) {
41 if ((flags & RNDF_X128) == 0) {
42 continue;
44 } else if ((flags & RNDF_ETC) == 0) {
45 continue;
48 out[i] = v;
49 ++i;
52 std::uniform_int_distribution<std::mt19937::result_type> seed_dist(0, 0xffffffff);
53 s_rnd_next_seed = seed_dist(rng);
55 return len;
58 void RandomStringAppend(std::string &out, size_t min_len, size_t max_len, unsigned int flags)
60 const size_t orig_size = out.size();
61 out.resize(orig_size + max_len);
62 size_t len = RandomStringBuffer(&out[orig_size], min_len, max_len, flags);
63 out.resize(orig_size + len);