forked from igor-sadchenko/BaseNCode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
base32.cpp
115 lines (100 loc) · 1.92 KB
/
base32.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Base32 implementation
//
#include "base32.h"
std::string base32_encode(const std::string &data)
{
std::string res;
res.reserve((size_t)(data.size() * 1.6 + 1));
int count = 0;
if (!data.empty())
{
int buffer = data[0];
size_t next = 1;
int bitsLeft = 8;
while ((bitsLeft > 0 || next < data.length()))
{
if (bitsLeft < 5)
{
if (next < data.length())
{
buffer <<= 8;
buffer |= data[next++] & 0xFF;
bitsLeft += 8;
}
else
{
int pad = 5 - bitsLeft;
buffer <<= pad;
bitsLeft += pad;
}
}
size_t index = 0x1F & (buffer >> (bitsLeft - 5));
bitsLeft -= 5;
res += '\0';
res[count++] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567"[index];
}
}
return res;
}
std::string base32_decode(const std::string &encoded)
{
std::string res;
res.reserve(encoded.size());
int buffer = 0;
int bitsLeft = 0;
int count = 0;
for (size_t i = 0; i < encoded.length(); ++i)
{
uint8_t ch = encoded[i];
if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n' || ch == '-')
{
continue;
}
buffer <<= 5;
// Deal with commonly mistyped characters
if (ch == '0')
{
ch = 'O';
}
else if (ch == '1')
{
ch = 'L';
}
else if (ch == '8')
{
ch = 'B';
}
// Look up one base32 digit
if ((ch >= 'A' && ch <= 'Z') || (ch >= 'a' && ch <= 'z'))
{
ch = (ch & 0x1F) - 1;
}
else if (ch >= '2' && ch <= '7')
{
ch -= '2' - 26;
}
else
{
throw std::exception("Bad base32 symbol");
}
buffer |= ch;
bitsLeft += 5;
if (bitsLeft >= 8)
{
res += '\0';
res[count++] = (char)(buffer >> (bitsLeft - 8));
bitsLeft -= 8;
}
}
return res;
}
std::string GroupStringByHyphens(const std::string &s, unsigned int symbols_in_group)
{
std::string res;
for (size_t curr_offset = 0; curr_offset < s.length(); curr_offset += symbols_in_group)
{
if (!res.empty()) res += "-";
res += s.substr(curr_offset, symbols_in_group);
}
return res;
}