Bitcoin Core  22.99.0
P2P Digital Currency
strencodings.cpp
Go to the documentation of this file.
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2020 The Bitcoin Core developers
3 // Distributed under the MIT software license, see the accompanying
4 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
5 
6 #include <util/strencodings.h>
7 #include <util/string.h>
8 
9 #include <tinyformat.h>
10 
11 #include <algorithm>
12 #include <cstdlib>
13 #include <cstring>
14 #include <optional>
15 
16 static const std::string CHARS_ALPHA_NUM = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
17 
18 static const std::string SAFE_CHARS[] =
19 {
20  CHARS_ALPHA_NUM + " .,;-_/:?@()", // SAFE_CHARS_DEFAULT
21  CHARS_ALPHA_NUM + " .,;-_?@", // SAFE_CHARS_UA_COMMENT
22  CHARS_ALPHA_NUM + ".-_", // SAFE_CHARS_FILENAME
23  CHARS_ALPHA_NUM + "!*'();:@&=+$,/?#[]-_.~%", // SAFE_CHARS_URI
24 };
25 
26 std::string SanitizeString(const std::string& str, int rule)
27 {
28  std::string strResult;
29  for (std::string::size_type i = 0; i < str.size(); i++)
30  {
31  if (SAFE_CHARS[rule].find(str[i]) != std::string::npos)
32  strResult.push_back(str[i]);
33  }
34  return strResult;
35 }
36 
37 const signed char p_util_hexdigit[256] =
38 { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
39  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
40  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
41  0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
42  -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
43  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
44  -1,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
45  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
46  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
47  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
48  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
49  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
50  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
51  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
52  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
53  -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, };
54 
55 signed char HexDigit(char c)
56 {
57  return p_util_hexdigit[(unsigned char)c];
58 }
59 
60 bool IsHex(const std::string& str)
61 {
62  for(std::string::const_iterator it(str.begin()); it != str.end(); ++it)
63  {
64  if (HexDigit(*it) < 0)
65  return false;
66  }
67  return (str.size() > 0) && (str.size()%2 == 0);
68 }
69 
70 bool IsHexNumber(const std::string& str)
71 {
72  size_t starting_location = 0;
73  if (str.size() > 2 && *str.begin() == '0' && *(str.begin()+1) == 'x') {
74  starting_location = 2;
75  }
76  for (const char c : str.substr(starting_location)) {
77  if (HexDigit(c) < 0) return false;
78  }
79  // Return false for empty string or "0x".
80  return (str.size() > starting_location);
81 }
82 
83 std::vector<unsigned char> ParseHex(const char* psz)
84 {
85  // convert hex dump to vector
86  std::vector<unsigned char> vch;
87  while (true)
88  {
89  while (IsSpace(*psz))
90  psz++;
91  signed char c = HexDigit(*psz++);
92  if (c == (signed char)-1)
93  break;
94  unsigned char n = (c << 4);
95  c = HexDigit(*psz++);
96  if (c == (signed char)-1)
97  break;
98  n |= c;
99  vch.push_back(n);
100  }
101  return vch;
102 }
103 
104 std::vector<unsigned char> ParseHex(const std::string& str)
105 {
106  return ParseHex(str.c_str());
107 }
108 
109 void SplitHostPort(std::string in, uint16_t& portOut, std::string& hostOut)
110 {
111  size_t colon = in.find_last_of(':');
112  // if a : is found, and it either follows a [...], or no other : is in the string, treat it as port separator
113  bool fHaveColon = colon != in.npos;
114  bool fBracketed = fHaveColon && (in[0] == '[' && in[colon - 1] == ']'); // if there is a colon, and in[0]=='[', colon is not 0, so in[colon-1] is safe
115  bool fMultiColon = fHaveColon && (in.find_last_of(':', colon - 1) != in.npos);
116  if (fHaveColon && (colon == 0 || fBracketed || !fMultiColon)) {
117  uint16_t n;
118  if (ParseUInt16(in.substr(colon + 1), &n)) {
119  in = in.substr(0, colon);
120  portOut = n;
121  }
122  }
123  if (in.size() > 0 && in[0] == '[' && in[in.size() - 1] == ']') {
124  hostOut = in.substr(1, in.size() - 2);
125  } else {
126  hostOut = in;
127  }
128 }
129 
131 {
132  static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
133 
134  std::string str;
135  str.reserve(((input.size() + 2) / 3) * 4);
136  ConvertBits<8, 6, true>([&](int v) { str += pbase64[v]; }, input.begin(), input.end());
137  while (str.size() % 4) str += '=';
138  return str;
139 }
140 
141 std::string EncodeBase64(const std::string& str)
142 {
143  return EncodeBase64(MakeUCharSpan(str));
144 }
145 
146 std::vector<unsigned char> DecodeBase64(const char* p, bool* pf_invalid)
147 {
148  static const int decode64_table[256] =
149  {
150  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
151  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
152  -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
153  -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
154  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
155  29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
156  49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
157  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
158  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
159  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
160  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
161  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
162  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
163  };
164 
165  const char* e = p;
166  std::vector<uint8_t> val;
167  val.reserve(strlen(p));
168  while (*p != 0) {
169  int x = decode64_table[(unsigned char)*p];
170  if (x == -1) break;
171  val.push_back(x);
172  ++p;
173  }
174 
175  std::vector<unsigned char> ret;
176  ret.reserve((val.size() * 3) / 4);
177  bool valid = ConvertBits<6, 8, false>([&](unsigned char c) { ret.push_back(c); }, val.begin(), val.end());
178 
179  const char* q = p;
180  while (valid && *p != 0) {
181  if (*p != '=') {
182  valid = false;
183  break;
184  }
185  ++p;
186  }
187  valid = valid && (p - e) % 4 == 0 && p - q < 4;
188  if (pf_invalid) *pf_invalid = !valid;
189 
190  return ret;
191 }
192 
193 std::string DecodeBase64(const std::string& str, bool* pf_invalid)
194 {
195  if (!ValidAsCString(str)) {
196  if (pf_invalid) {
197  *pf_invalid = true;
198  }
199  return {};
200  }
201  std::vector<unsigned char> vchRet = DecodeBase64(str.c_str(), pf_invalid);
202  return std::string((const char*)vchRet.data(), vchRet.size());
203 }
204 
205 std::string EncodeBase32(Span<const unsigned char> input, bool pad)
206 {
207  static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567";
208 
209  std::string str;
210  str.reserve(((input.size() + 4) / 5) * 8);
211  ConvertBits<8, 5, true>([&](int v) { str += pbase32[v]; }, input.begin(), input.end());
212  if (pad) {
213  while (str.size() % 8) {
214  str += '=';
215  }
216  }
217  return str;
218 }
219 
220 std::string EncodeBase32(const std::string& str, bool pad)
221 {
222  return EncodeBase32(MakeUCharSpan(str), pad);
223 }
224 
225 std::vector<unsigned char> DecodeBase32(const char* p, bool* pf_invalid)
226 {
227  static const int decode32_table[256] =
228  {
229  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
230  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
231  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,
232  -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
233  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 0, 1, 2,
234  3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
235  23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
236  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
237  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
238  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
239  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
240  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
241  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
242  };
243 
244  const char* e = p;
245  std::vector<uint8_t> val;
246  val.reserve(strlen(p));
247  while (*p != 0) {
248  int x = decode32_table[(unsigned char)*p];
249  if (x == -1) break;
250  val.push_back(x);
251  ++p;
252  }
253 
254  std::vector<unsigned char> ret;
255  ret.reserve((val.size() * 5) / 8);
256  bool valid = ConvertBits<5, 8, false>([&](unsigned char c) { ret.push_back(c); }, val.begin(), val.end());
257 
258  const char* q = p;
259  while (valid && *p != 0) {
260  if (*p != '=') {
261  valid = false;
262  break;
263  }
264  ++p;
265  }
266  valid = valid && (p - e) % 8 == 0 && p - q < 8;
267  if (pf_invalid) *pf_invalid = !valid;
268 
269  return ret;
270 }
271 
272 std::string DecodeBase32(const std::string& str, bool* pf_invalid)
273 {
274  if (!ValidAsCString(str)) {
275  if (pf_invalid) {
276  *pf_invalid = true;
277  }
278  return {};
279  }
280  std::vector<unsigned char> vchRet = DecodeBase32(str.c_str(), pf_invalid);
281  return std::string((const char*)vchRet.data(), vchRet.size());
282 }
283 
284 namespace {
285 template <typename T>
286 bool ParseIntegral(const std::string& str, T* out)
287 {
288  static_assert(std::is_integral<T>::value);
289  // Replicate the exact behavior of strtol/strtoll/strtoul/strtoull when
290  // handling leading +/- for backwards compatibility.
291  if (str.length() >= 2 && str[0] == '+' && str[1] == '-') {
292  return false;
293  }
294  const std::optional<T> opt_int = ToIntegral<T>((!str.empty() && str[0] == '+') ? str.substr(1) : str);
295  if (!opt_int) {
296  return false;
297  }
298  if (out != nullptr) {
299  *out = *opt_int;
300  }
301  return true;
302 }
303 }; // namespace
304 
305 bool ParseInt32(const std::string& str, int32_t* out)
306 {
307  return ParseIntegral<int32_t>(str, out);
308 }
309 
310 bool ParseInt64(const std::string& str, int64_t* out)
311 {
312  return ParseIntegral<int64_t>(str, out);
313 }
314 
315 bool ParseUInt8(const std::string& str, uint8_t* out)
316 {
317  return ParseIntegral<uint8_t>(str, out);
318 }
319 
320 bool ParseUInt16(const std::string& str, uint16_t* out)
321 {
322  return ParseIntegral<uint16_t>(str, out);
323 }
324 
325 bool ParseUInt32(const std::string& str, uint32_t* out)
326 {
327  return ParseIntegral<uint32_t>(str, out);
328 }
329 
330 bool ParseUInt64(const std::string& str, uint64_t* out)
331 {
332  return ParseIntegral<uint64_t>(str, out);
333 }
334 
335 std::string FormatParagraph(const std::string& in, size_t width, size_t indent)
336 {
337  std::stringstream out;
338  size_t ptr = 0;
339  size_t indented = 0;
340  while (ptr < in.size())
341  {
342  size_t lineend = in.find_first_of('\n', ptr);
343  if (lineend == std::string::npos) {
344  lineend = in.size();
345  }
346  const size_t linelen = lineend - ptr;
347  const size_t rem_width = width - indented;
348  if (linelen <= rem_width) {
349  out << in.substr(ptr, linelen + 1);
350  ptr = lineend + 1;
351  indented = 0;
352  } else {
353  size_t finalspace = in.find_last_of(" \n", ptr + rem_width);
354  if (finalspace == std::string::npos || finalspace < ptr) {
355  // No place to break; just include the entire word and move on
356  finalspace = in.find_first_of("\n ", ptr);
357  if (finalspace == std::string::npos) {
358  // End of the string, just add it and break
359  out << in.substr(ptr);
360  break;
361  }
362  }
363  out << in.substr(ptr, finalspace - ptr) << "\n";
364  if (in[finalspace] == '\n') {
365  indented = 0;
366  } else if (indent) {
367  out << std::string(indent, ' ');
368  indented = indent;
369  }
370  ptr = finalspace + 1;
371  }
372  }
373  return out.str();
374 }
375 
384 static const int64_t UPPER_BOUND = 1000000000000000000LL - 1LL;
385 
387 static inline bool ProcessMantissaDigit(char ch, int64_t &mantissa, int &mantissa_tzeros)
388 {
389  if(ch == '0')
390  ++mantissa_tzeros;
391  else {
392  for (int i=0; i<=mantissa_tzeros; ++i) {
393  if (mantissa > (UPPER_BOUND / 10LL))
394  return false; /* overflow */
395  mantissa *= 10;
396  }
397  mantissa += ch - '0';
398  mantissa_tzeros = 0;
399  }
400  return true;
401 }
402 
403 bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
404 {
405  int64_t mantissa = 0;
406  int64_t exponent = 0;
407  int mantissa_tzeros = 0;
408  bool mantissa_sign = false;
409  bool exponent_sign = false;
410  int ptr = 0;
411  int end = val.size();
412  int point_ofs = 0;
413 
414  if (ptr < end && val[ptr] == '-') {
415  mantissa_sign = true;
416  ++ptr;
417  }
418  if (ptr < end)
419  {
420  if (val[ptr] == '0') {
421  /* pass single 0 */
422  ++ptr;
423  } else if (val[ptr] >= '1' && val[ptr] <= '9') {
424  while (ptr < end && IsDigit(val[ptr])) {
425  if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros))
426  return false; /* overflow */
427  ++ptr;
428  }
429  } else return false; /* missing expected digit */
430  } else return false; /* empty string or loose '-' */
431  if (ptr < end && val[ptr] == '.')
432  {
433  ++ptr;
434  if (ptr < end && IsDigit(val[ptr]))
435  {
436  while (ptr < end && IsDigit(val[ptr])) {
437  if (!ProcessMantissaDigit(val[ptr], mantissa, mantissa_tzeros))
438  return false; /* overflow */
439  ++ptr;
440  ++point_ofs;
441  }
442  } else return false; /* missing expected digit */
443  }
444  if (ptr < end && (val[ptr] == 'e' || val[ptr] == 'E'))
445  {
446  ++ptr;
447  if (ptr < end && val[ptr] == '+')
448  ++ptr;
449  else if (ptr < end && val[ptr] == '-') {
450  exponent_sign = true;
451  ++ptr;
452  }
453  if (ptr < end && IsDigit(val[ptr])) {
454  while (ptr < end && IsDigit(val[ptr])) {
455  if (exponent > (UPPER_BOUND / 10LL))
456  return false; /* overflow */
457  exponent = exponent * 10 + val[ptr] - '0';
458  ++ptr;
459  }
460  } else return false; /* missing expected digit */
461  }
462  if (ptr != end)
463  return false; /* trailing garbage */
464 
465  /* finalize exponent */
466  if (exponent_sign)
467  exponent = -exponent;
468  exponent = exponent - point_ofs + mantissa_tzeros;
469 
470  /* finalize mantissa */
471  if (mantissa_sign)
472  mantissa = -mantissa;
473 
474  /* convert to one 64-bit fixed-point value */
475  exponent += decimals;
476  if (exponent < 0)
477  return false; /* cannot represent values smaller than 10^-decimals */
478  if (exponent >= 18)
479  return false; /* cannot represent values larger than or equal to 10^(18-decimals) */
480 
481  for (int i=0; i < exponent; ++i) {
482  if (mantissa > (UPPER_BOUND / 10LL) || mantissa < -(UPPER_BOUND / 10LL))
483  return false; /* overflow */
484  mantissa *= 10;
485  }
486  if (mantissa > UPPER_BOUND || mantissa < -UPPER_BOUND)
487  return false; /* overflow */
488 
489  if (amount_out)
490  *amount_out = mantissa;
491 
492  return true;
493 }
494 
495 std::string ToLower(const std::string& str)
496 {
497  std::string r;
498  for (auto ch : str) r += ToLower((unsigned char)ch);
499  return r;
500 }
501 
502 std::string ToUpper(const std::string& str)
503 {
504  std::string r;
505  for (auto ch : str) r += ToUpper((unsigned char)ch);
506  return r;
507 }
508 
509 std::string Capitalize(std::string str)
510 {
511  if (str.empty()) return str;
512  str[0] = ToUpper(str.front());
513  return str;
514 }
515 
516 std::string HexStr(const Span<const uint8_t> s)
517 {
518  std::string rv(s.size() * 2, '\0');
519  static constexpr char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
520  '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
521  auto it = rv.begin();
522  for (uint8_t v : s) {
523  *it++ = hexmap[v >> 4];
524  *it++ = hexmap[v & 15];
525  }
526  assert(it == rv.end());
527  return rv;
528 }
ParseInt64
bool ParseInt64(const std::string &str, int64_t *out)
Convert string to signed 64-bit integer with strict parse error feedback.
Definition: strencodings.cpp:310
ParseHex
std::vector< unsigned char > ParseHex(const char *psz)
Definition: strencodings.cpp:83
assert
assert(!tx.IsCoinBase())
ParseFixedPoint
bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out)
Parse number as fixed point according to JSON number syntax.
Definition: strencodings.cpp:403
IsHexNumber
bool IsHexNumber(const std::string &str)
Return true if the string is a hex number, optionally prefixed with "0x".
Definition: strencodings.cpp:70
MakeUCharSpan
constexpr auto MakeUCharSpan(V &&v) -> decltype(UCharSpanCast(MakeSpan(std::forward< V >(v))))
Like MakeSpan, but for (const) unsigned char member types only.
Definition: span.h:249
string.h
IsHex
bool IsHex(const std::string &str)
Definition: strencodings.cpp:60
EncodeBase64
std::string EncodeBase64(Span< const unsigned char > input)
Definition: strencodings.cpp:130
ValidAsCString
bool ValidAsCString(const std::string &str) noexcept
Check if a string does not contain any embedded NUL (\0) characters.
Definition: string.h:78
ParseUInt16
bool ParseUInt16(const std::string &str, uint16_t *out)
Convert decimal string to unsigned 16-bit integer with strict parse error feedback.
Definition: strencodings.cpp:320
IsSpace
constexpr bool IsSpace(char c) noexcept
Tests if the given character is a whitespace character.
Definition: strencodings.h:121
tinyformat.h
Span::size
constexpr std::size_t size() const noexcept
Definition: span.h:182
Span
A Span is an object that can refer to a contiguous sequence of objects.
Definition: span.h:92
strencodings.h
p_util_hexdigit
const signed char p_util_hexdigit[256]
Definition: strencodings.cpp:37
SplitHostPort
void SplitHostPort(std::string in, uint16_t &portOut, std::string &hostOut)
Definition: strencodings.cpp:109
UPPER_BOUND
static const int64_t UPPER_BOUND
Upper bound for mantissa.
Definition: strencodings.cpp:384
HexDigit
signed char HexDigit(char c)
Definition: strencodings.cpp:55
DecodeBase64
std::vector< unsigned char > DecodeBase64(const char *p, bool *pf_invalid)
Definition: strencodings.cpp:146
Span::begin
constexpr C * begin() const noexcept
Definition: span.h:170
Capitalize
std::string Capitalize(std::string str)
Capitalizes the first character of the given string.
Definition: strencodings.cpp:509
ToUpper
std::string ToUpper(const std::string &str)
Returns the uppercase equivalent of the given string.
Definition: strencodings.cpp:502
CHARS_ALPHA_NUM
static const std::string CHARS_ALPHA_NUM
Definition: strencodings.cpp:16
EncodeBase32
std::string EncodeBase32(Span< const unsigned char > input, bool pad)
Base32 encode.
Definition: strencodings.cpp:205
IsDigit
constexpr bool IsDigit(char c)
Tests if the given character is a decimal digit.
Definition: strencodings.h:105
DecodeBase32
std::vector< unsigned char > DecodeBase32(const char *p, bool *pf_invalid)
Definition: strencodings.cpp:225
ParseUInt64
bool ParseUInt64(const std::string &str, uint64_t *out)
Convert decimal string to unsigned 64-bit integer with strict parse error feedback.
Definition: strencodings.cpp:330
SAFE_CHARS
static const std::string SAFE_CHARS[]
Definition: strencodings.cpp:18
ParseInt32
bool ParseInt32(const std::string &str, int32_t *out)
Convert string to signed 32-bit integer with strict parse error feedback.
Definition: strencodings.cpp:305
SanitizeString
std::string SanitizeString(const std::string &str, int rule)
Remove unsafe chars.
Definition: strencodings.cpp:26
T
#define T(expected, seed, data)
HexStr
std::string HexStr(const Span< const uint8_t > s)
Convert a span of bytes to a lower-case hexadecimal string.
Definition: strencodings.cpp:516
ParseUInt8
bool ParseUInt8(const std::string &str, uint8_t *out)
Convert decimal string to unsigned 8-bit integer with strict parse error feedback.
Definition: strencodings.cpp:315
ProcessMantissaDigit
static bool ProcessMantissaDigit(char ch, int64_t &mantissa, int &mantissa_tzeros)
Helper function for ParseFixedPoint.
Definition: strencodings.cpp:387
Span::end
constexpr C * end() const noexcept
Definition: span.h:171
ParseUInt32
bool ParseUInt32(const std::string &str, uint32_t *out)
Convert decimal string to unsigned 32-bit integer with strict parse error feedback.
Definition: strencodings.cpp:325
FormatParagraph
std::string FormatParagraph(const std::string &in, size_t width, size_t indent)
Format a paragraph of text to a fixed width, adding spaces for indentation to any added line.
Definition: strencodings.cpp:335
ToLower
std::string ToLower(const std::string &str)
Returns the lowercase equivalent of the given string.
Definition: strencodings.cpp:495