1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2018 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 /**
7 * Utilities for converting data from/to strings.
8 */
9 #ifndef BITCOIN_UTIL_STRENCODINGS_H
10 #define BITCOIN_UTIL_STRENCODINGS_H
11
12 #include <attributes.h>
13
14 #include <cstdint>
15 #include <string>
16 #include <vector>
17
18 #define ARRAYLEN(array) (sizeof(array)/sizeof((array)[0]))
19 #define BEGIN(a) ((char*)&(a))
20
21 /** Used by SanitizeString() */
22 enum SafeChars
23 {
24 SAFE_CHARS_DEFAULT, //!< The full set of allowed chars
25 SAFE_CHARS_UA_COMMENT, //!< BIP-0014 subset
26 SAFE_CHARS_FILENAME, //!< Chars allowed in filenames
27 SAFE_CHARS_URI, //!< Chars allowed in URIs (RFC 3986)
28 };
29
30 /**
31 * Remove unsafe chars. Safe chars chosen to allow simple messages/URLs/email
32 * addresses, but avoid anything even possibly remotely dangerous like & or >
33 * @param[in] str The string to sanitize
34 * @param[in] rule The set of safe chars to choose (default: least restrictive)
35 * @return A new string without unsafe chars
36 */
37 std::string SanitizeString(const std::string& str, int rule = SAFE_CHARS_DEFAULT);
38 std::vector<unsigned char> ParseHex(const char* psz);
39 std::vector<unsigned char> ParseHex(const std::string& str);
40 signed char HexDigit(char c);
41 /* Returns true if each character in str is a hex character, and has an even
42 * number of hex digits.*/
43 bool IsHex(const std::string& str);
44 /**
45 * Return true if the string is a hex number, optionally prefixed with "0x"
46 */
47 bool IsHexNumber(const std::string& str);
48 std::vector<unsigned char> DecodeBase64(const char* p, bool* pf_invalid = nullptr);
49 std::string DecodeBase64(const std::string& str, bool* pf_invalid = nullptr);
50 std::string EncodeBase64(const unsigned char* pch, size_t len);
51 std::string EncodeBase64(const std::string& str);
52 std::vector<unsigned char> DecodeBase32(const char* p, bool* pf_invalid = nullptr);
53 std::string DecodeBase32(const std::string& str, bool* pf_invalid = nullptr);
54 std::string EncodeBase32(const unsigned char* pch, size_t len);
55 std::string EncodeBase32(const std::string& str);
56
57 void SplitHostPort(std::string in, int &portOut, std::string &hostOut);
58 std::string i64tostr(int64_t n);
59 std::string itostr(int n);
60 int64_t atoi64(const char* psz);
61 int64_t atoi64(const std::string& str);
62 int atoi(const std::string& str);
63
64 /**
65 * Tests if the given character is a decimal digit.
66 * @param[in] c character to test
67 * @return true if the argument is a decimal digit; otherwise false.
68 */
IsDigit(char c)69 constexpr bool IsDigit(char c)
70 {
71 return c >= '0' && c <= '9';
72 }
73
74 /**
75 * Tests if the given character is a whitespace character. The whitespace characters
76 * are: space, form-feed ('\f'), newline ('\n'), carriage return ('\r'), horizontal
77 * tab ('\t'), and vertical tab ('\v').
78 *
79 * This function is locale independent. Under the C locale this function gives the
80 * same result as std::isspace.
81 *
82 * @param[in] c character to test
83 * @return true if the argument is a whitespace character; otherwise false
84 */
IsSpace(char c)85 constexpr inline bool IsSpace(char c) noexcept {
86 return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v';
87 }
88
89 /**
90 * Convert string to signed 32-bit integer with strict parse error feedback.
91 * @returns true if the entire string could be parsed as valid integer,
92 * false if not the entire string could be parsed or when overflow or underflow occurred.
93 */
94 NODISCARD bool ParseInt32(const std::string& str, int32_t *out);
95
96 /**
97 * Convert string to signed 64-bit integer with strict parse error feedback.
98 * @returns true if the entire string could be parsed as valid integer,
99 * false if not the entire string could be parsed or when overflow or underflow occurred.
100 */
101 NODISCARD bool ParseInt64(const std::string& str, int64_t *out);
102
103 /**
104 * Convert decimal string to unsigned 32-bit integer with strict parse error feedback.
105 * @returns true if the entire string could be parsed as valid integer,
106 * false if not the entire string could be parsed or when overflow or underflow occurred.
107 */
108 NODISCARD bool ParseUInt32(const std::string& str, uint32_t *out);
109
110 /**
111 * Convert decimal string to unsigned 64-bit integer with strict parse error feedback.
112 * @returns true if the entire string could be parsed as valid integer,
113 * false if not the entire string could be parsed or when overflow or underflow occurred.
114 */
115 NODISCARD bool ParseUInt64(const std::string& str, uint64_t *out);
116
117 /**
118 * Convert string to double with strict parse error feedback.
119 * @returns true if the entire string could be parsed as valid double,
120 * false if not the entire string could be parsed or when overflow or underflow occurred.
121 */
122 NODISCARD bool ParseDouble(const std::string& str, double *out);
123
124 template<typename T>
125 std::string HexStr(const T itbegin, const T itend, bool fSpaces=false)
126 {
127 std::string rv;
128 static const char hexmap[16] = { '0', '1', '2', '3', '4', '5', '6', '7',
129 '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
130 rv.reserve((itend-itbegin)*3);
131 for(T it = itbegin; it < itend; ++it)
132 {
133 unsigned char val = (unsigned char)(*it);
134 if(fSpaces && it != itbegin)
135 rv.push_back(' ');
136 rv.push_back(hexmap[val>>4]);
137 rv.push_back(hexmap[val&15]);
138 }
139
140 return rv;
141 }
142
143 template<typename T>
144 inline std::string HexStr(const T& vch, bool fSpaces=false)
145 {
146 return HexStr(vch.begin(), vch.end(), fSpaces);
147 }
148
149 /**
150 * Format a paragraph of text to a fixed width, adding spaces for
151 * indentation to any added line.
152 */
153 std::string FormatParagraph(const std::string& in, size_t width = 79, size_t indent = 0);
154
155 /**
156 * Timing-attack-resistant comparison.
157 * Takes time proportional to length
158 * of first argument.
159 */
160 template <typename T>
TimingResistantEqual(const T & a,const T & b)161 bool TimingResistantEqual(const T& a, const T& b)
162 {
163 if (b.size() == 0) return a.size() == 0;
164 size_t accumulator = a.size() ^ b.size();
165 for (size_t i = 0; i < a.size(); i++)
166 accumulator |= a[i] ^ b[i%b.size()];
167 return accumulator == 0;
168 }
169
170 /** Parse number as fixed point according to JSON number syntax.
171 * See http://json.org/number.gif
172 * @returns true on success, false on error.
173 * @note The result must be in the range (-10^18,10^18), otherwise an overflow error will trigger.
174 */
175 NODISCARD bool ParseFixedPoint(const std::string &val, int decimals, int64_t *amount_out);
176
177 /** Convert from one power-of-2 number base to another. */
178 template<int frombits, int tobits, bool pad, typename O, typename I>
ConvertBits(const O & outfn,I it,I end)179 bool ConvertBits(const O& outfn, I it, I end) {
180 size_t acc = 0;
181 size_t bits = 0;
182 constexpr size_t maxv = (1 << tobits) - 1;
183 constexpr size_t max_acc = (1 << (frombits + tobits - 1)) - 1;
184 while (it != end) {
185 acc = ((acc << frombits) | *it) & max_acc;
186 bits += frombits;
187 while (bits >= tobits) {
188 bits -= tobits;
189 outfn((acc >> bits) & maxv);
190 }
191 ++it;
192 }
193 if (pad) {
194 if (bits) outfn((acc << (tobits - bits)) & maxv);
195 } else if (bits >= frombits || ((acc << (tobits - bits)) & maxv)) {
196 return false;
197 }
198 return true;
199 }
200
201 /**
202 * Converts the given character to its lowercase equivalent.
203 * This function is locale independent. It only converts uppercase
204 * characters in the standard 7-bit ASCII range.
205 * @param[in] c the character to convert to lowercase.
206 * @return the lowercase equivalent of c; or the argument
207 * if no conversion is possible.
208 */
ToLower(char c)209 constexpr char ToLower(char c)
210 {
211 return (c >= 'A' && c <= 'Z' ? (c - 'A') + 'a' : c);
212 }
213
214 /**
215 * Converts the given string to its lowercase equivalent.
216 * This function is locale independent. It only converts uppercase
217 * characters in the standard 7-bit ASCII range.
218 * @param[in,out] str the string to convert to lowercase.
219 */
220 void Downcase(std::string& str);
221
222 /**
223 * Converts the given character to its uppercase equivalent.
224 * This function is locale independent. It only converts lowercase
225 * characters in the standard 7-bit ASCII range.
226 * @param[in] c the character to convert to uppercase.
227 * @return the uppercase equivalent of c; or the argument
228 * if no conversion is possible.
229 */
ToUpper(char c)230 constexpr char ToUpper(char c)
231 {
232 return (c >= 'a' && c <= 'z' ? (c - 'a') + 'A' : c);
233 }
234
235 /**
236 * Capitalizes the first character of the given string.
237 * This function is locale independent. It only capitalizes the
238 * first character of the argument if it has an uppercase equivalent
239 * in the standard 7-bit ASCII range.
240 * @param[in] str the string to capitalize.
241 * @return string with the first letter capitalized.
242 */
243 std::string Capitalize(std::string str);
244
245 #endif // BITCOIN_UTIL_STRENCODINGS_H
246