]> Git Repo - VerusCoin.git/blob - src/utilstrencodings.cpp
Merge pull request #5349
[VerusCoin.git] / src / utilstrencodings.cpp
1 // Copyright (c) 2009-2010 Satoshi Nakamoto
2 // Copyright (c) 2009-2014 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 "utilstrencodings.h"
7
8 #include "tinyformat.h"
9
10 #include <cstdlib>
11 #include <cstring>
12 #include <errno.h>
13 #include <limits>
14
15 using namespace std;
16
17 string SanitizeString(const string& str)
18 {
19     /**
20      * safeChars chosen to allow simple messages/URLs/email addresses, but avoid anything
21      * even possibly remotely dangerous like & or >
22      */
23     static string safeChars("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890 .,;_/:?@()");
24     string strResult;
25     for (std::string::size_type i = 0; i < str.size(); i++)
26     {
27         if (safeChars.find(str[i]) != std::string::npos)
28             strResult.push_back(str[i]);
29     }
30     return strResult;
31 }
32
33 const signed char p_util_hexdigit[256] =
34 { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
35   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
36   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
37   0,1,2,3,4,5,6,7,8,9,-1,-1,-1,-1,-1,-1,
38   -1,0xa,0xb,0xc,0xd,0xe,0xf,-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,0xa,0xb,0xc,0xd,0xe,0xf,-1,-1,-1,-1,-1,-1,-1,-1,-1,
41   -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,
42   -1,-1,-1,-1,-1,-1,-1,-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,-1,-1,-1,-1,-1,-1,-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
51 signed char HexDigit(char c)
52 {
53     return p_util_hexdigit[(unsigned char)c];
54 }
55
56 bool IsHex(const string& str)
57 {
58     for(std::string::const_iterator it(str.begin()); it != str.end(); ++it)
59     {
60         if (HexDigit(*it) < 0)
61             return false;
62     }
63     return (str.size() > 0) && (str.size()%2 == 0);
64 }
65
66 vector<unsigned char> ParseHex(const char* psz)
67 {
68     // convert hex dump to vector
69     vector<unsigned char> vch;
70     while (true)
71     {
72         while (isspace(*psz))
73             psz++;
74         signed char c = HexDigit(*psz++);
75         if (c == (signed char)-1)
76             break;
77         unsigned char n = (c << 4);
78         c = HexDigit(*psz++);
79         if (c == (signed char)-1)
80             break;
81         n |= c;
82         vch.push_back(n);
83     }
84     return vch;
85 }
86
87 vector<unsigned char> ParseHex(const string& str)
88 {
89     return ParseHex(str.c_str());
90 }
91
92 string EncodeBase64(const unsigned char* pch, size_t len)
93 {
94     static const char *pbase64 = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
95
96     string strRet="";
97     strRet.reserve((len+2)/3*4);
98
99     int mode=0, left=0;
100     const unsigned char *pchEnd = pch+len;
101
102     while (pch<pchEnd)
103     {
104         int enc = *(pch++);
105         switch (mode)
106         {
107             case 0: // we have no bits
108                 strRet += pbase64[enc >> 2];
109                 left = (enc & 3) << 4;
110                 mode = 1;
111                 break;
112
113             case 1: // we have two bits
114                 strRet += pbase64[left | (enc >> 4)];
115                 left = (enc & 15) << 2;
116                 mode = 2;
117                 break;
118
119             case 2: // we have four bits
120                 strRet += pbase64[left | (enc >> 6)];
121                 strRet += pbase64[enc & 63];
122                 mode = 0;
123                 break;
124         }
125     }
126
127     if (mode)
128     {
129         strRet += pbase64[left];
130         strRet += '=';
131         if (mode == 1)
132             strRet += '=';
133     }
134
135     return strRet;
136 }
137
138 string EncodeBase64(const string& str)
139 {
140     return EncodeBase64((const unsigned char*)str.c_str(), str.size());
141 }
142
143 vector<unsigned char> DecodeBase64(const char* p, bool* pfInvalid)
144 {
145     static const int decode64_table[256] =
146     {
147         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
148         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
149         -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1,
150         -1, -1, -1, -1, -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
151         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28,
152         29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
153         49, 50, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
154         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
155         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
156         -1, -1, -1, -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
160     };
161
162     if (pfInvalid)
163         *pfInvalid = false;
164
165     vector<unsigned char> vchRet;
166     vchRet.reserve(strlen(p)*3/4);
167
168     int mode = 0;
169     int left = 0;
170
171     while (1)
172     {
173          int dec = decode64_table[(unsigned char)*p];
174          if (dec == -1) break;
175          p++;
176          switch (mode)
177          {
178              case 0: // we have no bits and get 6
179                  left = dec;
180                  mode = 1;
181                  break;
182
183               case 1: // we have 6 bits and keep 4
184                   vchRet.push_back((left<<2) | (dec>>4));
185                   left = dec & 15;
186                   mode = 2;
187                   break;
188
189              case 2: // we have 4 bits and get 6, we keep 2
190                  vchRet.push_back((left<<4) | (dec>>2));
191                  left = dec & 3;
192                  mode = 3;
193                  break;
194
195              case 3: // we have 2 bits and get 6
196                  vchRet.push_back((left<<6) | dec);
197                  mode = 0;
198                  break;
199          }
200     }
201
202     if (pfInvalid)
203         switch (mode)
204         {
205             case 0: // 4n base64 characters processed: ok
206                 break;
207
208             case 1: // 4n+1 base64 character processed: impossible
209                 *pfInvalid = true;
210                 break;
211
212             case 2: // 4n+2 base64 characters processed: require '=='
213                 if (left || p[0] != '=' || p[1] != '=' || decode64_table[(unsigned char)p[2]] != -1)
214                     *pfInvalid = true;
215                 break;
216
217             case 3: // 4n+3 base64 characters processed: require '='
218                 if (left || p[0] != '=' || decode64_table[(unsigned char)p[1]] != -1)
219                     *pfInvalid = true;
220                 break;
221         }
222
223     return vchRet;
224 }
225
226 string DecodeBase64(const string& str)
227 {
228     vector<unsigned char> vchRet = DecodeBase64(str.c_str());
229     return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size());
230 }
231
232 string EncodeBase32(const unsigned char* pch, size_t len)
233 {
234     static const char *pbase32 = "abcdefghijklmnopqrstuvwxyz234567";
235
236     string strRet="";
237     strRet.reserve((len+4)/5*8);
238
239     int mode=0, left=0;
240     const unsigned char *pchEnd = pch+len;
241
242     while (pch<pchEnd)
243     {
244         int enc = *(pch++);
245         switch (mode)
246         {
247             case 0: // we have no bits
248                 strRet += pbase32[enc >> 3];
249                 left = (enc & 7) << 2;
250                 mode = 1;
251                 break;
252
253             case 1: // we have three bits
254                 strRet += pbase32[left | (enc >> 6)];
255                 strRet += pbase32[(enc >> 1) & 31];
256                 left = (enc & 1) << 4;
257                 mode = 2;
258                 break;
259
260             case 2: // we have one bit
261                 strRet += pbase32[left | (enc >> 4)];
262                 left = (enc & 15) << 1;
263                 mode = 3;
264                 break;
265
266             case 3: // we have four bits
267                 strRet += pbase32[left | (enc >> 7)];
268                 strRet += pbase32[(enc >> 2) & 31];
269                 left = (enc & 3) << 3;
270                 mode = 4;
271                 break;
272
273             case 4: // we have two bits
274                 strRet += pbase32[left | (enc >> 5)];
275                 strRet += pbase32[enc & 31];
276                 mode = 0;
277         }
278     }
279
280     static const int nPadding[5] = {0, 6, 4, 3, 1};
281     if (mode)
282     {
283         strRet += pbase32[left];
284         for (int n=0; n<nPadding[mode]; n++)
285              strRet += '=';
286     }
287
288     return strRet;
289 }
290
291 string EncodeBase32(const string& str)
292 {
293     return EncodeBase32((const unsigned char*)str.c_str(), str.size());
294 }
295
296 vector<unsigned char> DecodeBase32(const char* p, bool* pfInvalid)
297 {
298     static const int decode32_table[256] =
299     {
300         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
301         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
302         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, -1, -1, -1, -1,
303         -1, -1, -1, -1, -1,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
304         15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, -1,  0,  1,  2,
305          3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
306         23, 24, 25, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
307         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
308         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
309         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
310         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
311         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
312         -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
313     };
314
315     if (pfInvalid)
316         *pfInvalid = false;
317
318     vector<unsigned char> vchRet;
319     vchRet.reserve((strlen(p))*5/8);
320
321     int mode = 0;
322     int left = 0;
323
324     while (1)
325     {
326          int dec = decode32_table[(unsigned char)*p];
327          if (dec == -1) break;
328          p++;
329          switch (mode)
330          {
331              case 0: // we have no bits and get 5
332                  left = dec;
333                  mode = 1;
334                  break;
335
336               case 1: // we have 5 bits and keep 2
337                   vchRet.push_back((left<<3) | (dec>>2));
338                   left = dec & 3;
339                   mode = 2;
340                   break;
341
342              case 2: // we have 2 bits and keep 7
343                  left = left << 5 | dec;
344                  mode = 3;
345                  break;
346
347              case 3: // we have 7 bits and keep 4
348                  vchRet.push_back((left<<1) | (dec>>4));
349                  left = dec & 15;
350                  mode = 4;
351                  break;
352
353              case 4: // we have 4 bits, and keep 1
354                  vchRet.push_back((left<<4) | (dec>>1));
355                  left = dec & 1;
356                  mode = 5;
357                  break;
358
359              case 5: // we have 1 bit, and keep 6
360                  left = left << 5 | dec;
361                  mode = 6;
362                  break;
363
364              case 6: // we have 6 bits, and keep 3
365                  vchRet.push_back((left<<2) | (dec>>3));
366                  left = dec & 7;
367                  mode = 7;
368                  break;
369
370              case 7: // we have 3 bits, and keep 0
371                  vchRet.push_back((left<<5) | dec);
372                  mode = 0;
373                  break;
374          }
375     }
376
377     if (pfInvalid)
378         switch (mode)
379         {
380             case 0: // 8n base32 characters processed: ok
381                 break;
382
383             case 1: // 8n+1 base32 characters processed: impossible
384             case 3: //   +3
385             case 6: //   +6
386                 *pfInvalid = true;
387                 break;
388
389             case 2: // 8n+2 base32 characters processed: require '======'
390                 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || p[4] != '=' || p[5] != '=' || decode32_table[(unsigned char)p[6]] != -1)
391                     *pfInvalid = true;
392                 break;
393
394             case 4: // 8n+4 base32 characters processed: require '===='
395                 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || p[3] != '=' || decode32_table[(unsigned char)p[4]] != -1)
396                     *pfInvalid = true;
397                 break;
398
399             case 5: // 8n+5 base32 characters processed: require '==='
400                 if (left || p[0] != '=' || p[1] != '=' || p[2] != '=' || decode32_table[(unsigned char)p[3]] != -1)
401                     *pfInvalid = true;
402                 break;
403
404             case 7: // 8n+7 base32 characters processed: require '='
405                 if (left || p[0] != '=' || decode32_table[(unsigned char)p[1]] != -1)
406                     *pfInvalid = true;
407                 break;
408         }
409
410     return vchRet;
411 }
412
413 string DecodeBase32(const string& str)
414 {
415     vector<unsigned char> vchRet = DecodeBase32(str.c_str());
416     return (vchRet.size() == 0) ? string() : string((const char*)&vchRet[0], vchRet.size());
417 }
418
419 bool ParseInt32(const std::string& str, int32_t *out)
420 {
421     char *endp = NULL;
422     errno = 0; // strtol will not set errno if valid
423     long int n = strtol(str.c_str(), &endp, 10);
424     if(out) *out = (int)n;
425     // Note that strtol returns a *long int*, so even if strtol doesn't report a over/underflow
426     // we still have to check that the returned value is within the range of an *int32_t*. On 64-bit
427     // platforms the size of these types may be different.
428     return endp && *endp == 0 && !errno &&
429         n >= std::numeric_limits<int32_t>::min() &&
430         n <= std::numeric_limits<int32_t>::max();
431 }
432
433 std::string FormatParagraph(const std::string in, size_t width, size_t indent)
434 {
435     std::stringstream out;
436     size_t col = 0;
437     size_t ptr = 0;
438     while(ptr < in.size())
439     {
440         // Find beginning of next word
441         ptr = in.find_first_not_of(' ', ptr);
442         if (ptr == std::string::npos)
443             break;
444         // Find end of next word
445         size_t endword = in.find_first_of(' ', ptr);
446         if (endword == std::string::npos)
447             endword = in.size();
448         // Add newline and indentation if this wraps over the allowed width
449         if (col > 0)
450         {
451             if ((col + endword - ptr) > width)
452             {
453                 out << '\n';
454                 for(size_t i=0; i<indent; ++i)
455                     out << ' ';
456                 col = 0;
457             } else
458                 out << ' ';
459         }
460         // Append word
461         out << in.substr(ptr, endword - ptr);
462         col += endword - ptr + 1;
463         ptr = endword;
464     }
465     return out.str();
466 }
467
468 std::string i64tostr(int64_t n)
469 {
470     return strprintf("%d", n);
471 }
472
473 std::string itostr(int n)
474 {
475     return strprintf("%d", n);
476 }
477
478 int64_t atoi64(const char* psz)
479 {
480 #ifdef _MSC_VER
481     return _atoi64(psz);
482 #else
483     return strtoll(psz, NULL, 10);
484 #endif
485 }
486
487 int64_t atoi64(const std::string& str)
488 {
489 #ifdef _MSC_VER
490     return _atoi64(str.c_str());
491 #else
492     return strtoll(str.c_str(), NULL, 10);
493 #endif
494 }
495
496 int atoi(const std::string& str)
497 {
498     return atoi(str.c_str());
499 }
This page took 0.051581 seconds and 4 git commands to generate.