9#include <multibase/algorithm.h>
10#include <multibase/encoding.h>
22 static const std::array<char, 0> charset;
23 static const char name[];
24 static const char padding = 0;
30template <encoding T,
typename Traits = traits<T>>
37 std::string
process(std::string_view input)
override;
40 constexpr size_t input_size() {
return ratio.den; }
47 std::string
process(std::string_view input)
override;
50 constexpr size_t input_size() {
return ratio.num; }
54 constexpr static auto first = Traits::charset.cbegin();
55 constexpr static auto last = Traits::charset.cend();
56 using CharsetT =
decltype(Traits::charset);
57 using value_type =
typename CharsetT::value_type;
58 using iterator =
typename CharsetT::const_iterator;
61 constexpr static iterator find(iterator b, iterator e,
62 value_type
const& v)
noexcept {
63 return (b != e && *b != v) ? find(++b, e, v) : b;
68 constexpr static unsigned char getval(
unsigned char p)
noexcept {
69 return find(first, last, p) == last
70 ?
static_cast<unsigned char>(255)
71 : static_cast<unsigned char>(
72 std::distance(first, find(first, last, p)));
76 constexpr static std::intmax_t log2(std::intmax_t n)
noexcept {
77 return (n == 1) ? 0 : ((n < 2) ? 1 : 1 + log2(n / 2));
81 constexpr static auto radix =
sizeof(Traits::charset) /
sizeof(value_type);
83 constexpr static auto ratio = std::ratio<log2(256), log2(radix)>{};
85 static const std::array<unsigned char, 256> valset;
87 constexpr static auto base = T;
90template <encoding T,
typename Traits>
91const std::array<unsigned char, 256> basic_algorithm<T, Traits>::valset = {
92 getval(0), getval(1), getval(2), getval(3), getval(4),
93 getval(5), getval(6), getval(7), getval(8), getval(9),
94 getval(10), getval(11), getval(12), getval(13), getval(14),
95 getval(15), getval(16), getval(17), getval(18), getval(19),
96 getval(20), getval(21), getval(22), getval(23), getval(24),
97 getval(25), getval(26), getval(27), getval(28), getval(29),
98 getval(30), getval(31), getval(32), getval(33), getval(34),
99 getval(35), getval(36), getval(37), getval(38), getval(39),
100 getval(40), getval(41), getval(42), getval(43), getval(44),
101 getval(45), getval(46), getval(47), getval(48), getval(49),
102 getval(50), getval(51), getval(52), getval(53), getval(54),
103 getval(55), getval(56), getval(57), getval(58), getval(59),
104 getval(60), getval(61), getval(62), getval(63), getval(64),
105 getval(65), getval(66), getval(67), getval(68), getval(69),
106 getval(70), getval(71), getval(72), getval(73), getval(74),
107 getval(75), getval(76), getval(77), getval(78), getval(79),
108 getval(80), getval(81), getval(82), getval(83), getval(84),
109 getval(85), getval(86), getval(87), getval(88), getval(89),
110 getval(90), getval(91), getval(92), getval(93), getval(94),
111 getval(95), getval(96), getval(97), getval(98), getval(99),
112 getval(100), getval(101), getval(102), getval(103), getval(104),
113 getval(105), getval(106), getval(107), getval(108), getval(109),
114 getval(110), getval(111), getval(112), getval(113), getval(114),
115 getval(115), getval(116), getval(117), getval(118), getval(119),
116 getval(120), getval(121), getval(122), getval(123), getval(124),
117 getval(125), getval(126), getval(127), getval(128), getval(129),
118 getval(130), getval(131), getval(132), getval(133), getval(134),
119 getval(135), getval(136), getval(137), getval(138), getval(139),
120 getval(140), getval(141), getval(142), getval(143), getval(144),
121 getval(145), getval(146), getval(147), getval(148), getval(149),
122 getval(150), getval(151), getval(152), getval(153), getval(154),
123 getval(155), getval(156), getval(157), getval(158), getval(159),
124 getval(160), getval(161), getval(162), getval(163), getval(164),
125 getval(165), getval(166), getval(167), getval(168), getval(169),
126 getval(170), getval(171), getval(172), getval(173), getval(174),
127 getval(175), getval(176), getval(177), getval(178), getval(179),
128 getval(180), getval(181), getval(182), getval(183), getval(184),
129 getval(185), getval(186), getval(187), getval(188), getval(189),
130 getval(190), getval(191), getval(192), getval(193), getval(194),
131 getval(195), getval(196), getval(197), getval(198), getval(199),
132 getval(200), getval(201), getval(202), getval(203), getval(204),
133 getval(205), getval(206), getval(207), getval(208), getval(209),
134 getval(210), getval(211), getval(212), getval(213), getval(214),
135 getval(215), getval(216), getval(217), getval(218), getval(219),
136 getval(220), getval(221), getval(222), getval(223), getval(224),
137 getval(225), getval(226), getval(227), getval(228), getval(229),
138 getval(230), getval(231), getval(232), getval(233), getval(234),
139 getval(235), getval(236), getval(237), getval(238), getval(239),
140 getval(240), getval(241), getval(242), getval(243), getval(244),
141 getval(245), getval(246), getval(247), getval(248), getval(249),
142 getval(250), getval(251), getval(252), getval(253), getval(254),
145template <encoding T,
typename Traits>
147 std::string_view input) {
149 std::size_t isize = input.size();
150 auto partial_blocks =
static_cast<float>(input.size()) / input_size();
151 auto num_blocks =
static_cast<std::size_t
>(partial_blocks);
152 auto osize =
static_cast<size_t>(std::ceil(partial_blocks *
output_size()));
153 if constexpr (std::is_same_v<typename Traits::execution_style, block_tag>) {
154 num_blocks =
static_cast<size_t>(std::ceil(partial_blocks));
155 isize = input_size() * num_blocks;
157 output.resize(std::max(osize, (
output_size() * num_blocks)));
158 auto input_it = std::begin(input);
160 for (std::size_t i = 0; i < isize; ++i, ++input_it) {
161 int carry = i >= input.size() ? 0 :
static_cast<unsigned char>(*input_it);
163 for (
auto oi = output.rbegin();
164 (oi != output.rend()) && (carry != 0 || j < length); ++oi, ++j) {
165 carry += 256 * (*oi);
166 auto byte = (
unsigned char*)(&(*oi));
167 *
byte = carry % radix;
172 std::transform(output.rbegin(), output.rend(), output.rbegin(),
173 [](
auto c) { return Traits::charset[c]; });
174 if constexpr (Traits::padding == 0) {
175 output.resize(osize);
177 auto pad_size = output.size() - osize;
178 output.replace(osize, pad_size, pad_size, Traits::padding);
180 if constexpr (std::is_same_v<typename Traits::execution_style, stream_tag>) {
181 output.erase(0, output.size() %
output_size() ? output.size() - length : 0);
186template <encoding T,
typename Traits>
188 return std::is_same_v<typename Traits::execution_style, block_tag>
193template <encoding T,
typename Traits>
198template <encoding T,
typename Traits>
200 return std::is_same_v<typename Traits::execution_style, block_tag>
205template <encoding T,
typename Traits>
210template <encoding T,
typename Traits>
212 std::string_view input) {
214 auto end = std::find(input.begin(), input.end(), Traits::padding);
215 size_t input_size = std::distance(input.begin(), end);
216 auto partial_blocks =
static_cast<float>(input_size) / this->input_size();
217 auto output_size =
static_cast<size_t>(this->output_size() * partial_blocks);
218 if constexpr (std::is_same_v<typename Traits::execution_style, block_tag>) {
219 std::size_t num_blocks = 0;
220 auto input_size_float =
static_cast<float>(input.size());
222 static_cast<size_t>(std::ceil(input_size_float / this->input_size()));
223 output.resize(this->output_size() * num_blocks);
224 input_size = this->input_size() * num_blocks;
226 output.resize(output_size);
228 auto input_it = input.begin();
229 for (
size_t i = 0; i < input_size; ++i, ++input_it) {
230 int carry = i > input.size() || *input_it == Traits::padding
232 : valset[(
unsigned char)(*input_it)];
238 auto j = output.size();
239 while (carry != 0 || j > 0) {
241 carry += radix *
static_cast<unsigned char>(output[index]);
242 output[index] =
static_cast<unsigned char>(carry % 256);
244 if (carry > 0 && index == 0) {
245 output.insert(0, 1, 0);
251 if constexpr (std::is_same_v<typename Traits::execution_style, block_tag>) {
252 output.erase(output_size, output.size());
259 constexpr static const std::array<char, 16> charset = {
260 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
261 '8',
'9',
'a',
'b',
'c',
'd',
'e',
'f'};
262 constexpr static const char name[] =
"base_16";
264 constexpr static const char padding = 0;
270 constexpr static const std::array<char, 36> charset = {
271 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
272 'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
273 'k',
'l',
'm',
'n',
'o',
'p',
'q',
'r',
's',
't',
274 'u',
'v',
'w',
'x',
'y',
'z'};
275 constexpr static const char name[] =
"base_36";
277 constexpr static const char padding = 0;
284 constexpr static const std::array<char, 58> charset = {
285 '1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'A',
'B',
'C',
'D',
'E',
'F',
286 'G',
'H',
'J',
'K',
'L',
'M',
'N',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
287 'X',
'Y',
'Z',
'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'm',
288 'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z'};
289 constexpr static const char name[] =
"base_58_btc";
291 constexpr static const char padding = 0;
297 constexpr static const std::array<char, 64> charset = {
298 'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
299 'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
300 'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
301 'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
302 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'+',
'/'};
303 constexpr static const char name[] =
"base_64_pad";
305 constexpr static const char padding =
'=';
311 constexpr static const std::array<char, 64> charset = {
312 'A',
'B',
'C',
'D',
'E',
'F',
'G',
'H',
'I',
'J',
'K',
'L',
'M',
313 'N',
'O',
'P',
'Q',
'R',
'S',
'T',
'U',
'V',
'W',
'X',
'Y',
'Z',
314 'a',
'b',
'c',
'd',
'e',
'f',
'g',
'h',
'i',
'j',
'k',
'l',
'm',
315 'n',
'o',
'p',
'q',
'r',
's',
't',
'u',
'v',
'w',
'x',
'y',
'z',
316 '0',
'1',
'2',
'3',
'4',
'5',
'6',
'7',
'8',
'9',
'+',
'/'};
317 constexpr static const char name[] =
"base_64";
320 constexpr static const char padding = 0;
Definition algorithm.h:13
Definition algorithm.h:16
Definition algorithm.h:10
Definition basic_algorithm.h:43
size_t block_size() override
Definition basic_algorithm.h:199
std::string process(std::string_view input) override
Definition basic_algorithm.h:211
size_t output_size() override
Definition basic_algorithm.h:206
Definition basic_algorithm.h:33
size_t output_size() override
Definition basic_algorithm.h:194
size_t block_size() override
Definition basic_algorithm.h:187
std::string process(std::string_view input) override
Definition basic_algorithm.h:146
Definition basic_algorithm.h:31
Definition basic_algorithm.h:21