comes in plain
[ghsmtp.git] / Pill.cpp
blobbe1ab4c2cb9eafd55c0a51226c941f1ae7ec411a
1 #include "Pill.hpp"
3 #include <limits>
5 #if __has_include(<experimental/random>)
6 #include <experimental/random>
7 #define HAS_RANDINT
8 #else
9 #include <random>
10 #endif
12 #include <boost/config.hpp>
14 Pill::Pill()
16 using s_t = decltype(s_);
18 #ifdef HAS_RANDINT
19 auto constexpr min = std::numeric_limits<s_t>::min();
20 auto constexpr max = std::numeric_limits<s_t>::max();
21 s_ = std::experimental::randint(min, max);
22 #else
23 std::random_device rd;
24 std::uniform_int_distribution<s_t> uni_dist;
25 s_ = uni_dist(rd);
26 #endif
28 auto resp{b32_ndigits_};
29 b32_str_[resp] = '\0';
31 // <http://philzimmermann.com/docs/human-oriented-base-32-encoding.txt>
33 constexpr char b32_charset[]{"ybndrfg8ejkmcpqxot1uwisza345h769"};
35 auto const os{reinterpret_cast<const unsigned char*>(&s_)};
36 auto osp{os + sizeof(s_)};
37 auto x{0ul};
39 switch ((osp - os) % 5) { // Duff's device
40 case 0:
41 do {
42 x = *--osp;
43 b32_str_[--resp] = b32_charset[x % 32];
44 x /= 32;
45 [[fallthrough]];
47 case 4:
48 x |= (static_cast<unsigned long>(*--osp)) << 3;
49 b32_str_[--resp] = b32_charset[x % 32];
50 x /= 32;
51 b32_str_[--resp] = b32_charset[x % 32];
52 x /= 32;
53 [[fallthrough]];
55 case 3:
56 x |= (static_cast<unsigned long>(*--osp)) << 1;
57 b32_str_[--resp] = b32_charset[x % 32];
58 x /= 32;
59 [[fallthrough]];
61 case 2:
62 x |= (static_cast<unsigned long>(*--osp)) << 4;
63 b32_str_[--resp] = b32_charset[x % 32];
64 x /= 32;
65 b32_str_[--resp] = b32_charset[x % 32];
66 x /= 32;
67 [[fallthrough]];
69 case 1:
70 x |= (static_cast<unsigned long>(*--osp)) << 2;
71 b32_str_[--resp] = b32_charset[x % 32];
72 x /= 32;
73 b32_str_[--resp] = b32_charset[x];
74 } while (osp > os);