Samchon Framework for CPP  1.0.0
Base64.cpp
1 #include <samchon/library/Base64.hpp>
2 
3 #include <array>
4 
5 using namespace std;
6 using namespace samchon;
7 using namespace samchon::library;
8 
9 /* -------------------------------------------------------------------------
10  ENCODE
11 ------------------------------------------------------------------------- */
12 auto Base64::encode(const ByteArray &byteArray) -> string
13 {
14  static array<char, 64> base64CharArray =
15  {
16  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
17  'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
18  'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
19  'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
20  'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
21  'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
22  'w', 'x', 'y', 'z', '0', '1', '2', '3',
23  '4', '5', '6', '7', '8', '9', '+', '/'
24  };
25 
26  unsigned char *bytes = (unsigned char*)byteArray.data();
27  string str;
28  str.reserve(byteArray.size() * 4);
29 
30  long long leftSize = (long long)byteArray.size();
31 
32  size_t i = 0;
33  size_t j = 0;
34  array<unsigned char, 3> input;
35  array<unsigned char, 4> output;
36 
37  while (leftSize--)
38  {
39  input[i++] = *(bytes++);
40  if (i == 3)
41  {
42  output[0] = (input[0] & 0xfc) >> 2;
43  output[1] = ((input[0] & 0x03) << 4) + ((input[1] & 0xf0) >> 4);
44  output[2] = ((input[1] & 0x0f) << 2) + ((input[2] & 0xc0) >> 6);
45  output[3] = input[2] & 0x3f;
46 
47  for (i = 0; (i < 4); i++)
48  str += base64CharArray[output[i]];
49  i = 0;
50  }
51  }
52 
53  if (i)
54  {
55  for (j = i; j < 3; j++)
56  input[j] = '\0';
57 
58  output[0] = (input[0] & 0xfc) >> 2;
59  output[1] = ((input[0] & 0x03) << 4) + ((input[1] & 0xf0) >> 4);
60  output[2] = ((input[1] & 0x0f) << 2) + ((input[2] & 0xc0) >> 6);
61  output[3] = input[2] & 0x3f;
62 
63  for (j = 0; (j < i + 1); j++)
64  str += base64CharArray[output[j]];
65 
66  while ((i++ < 3))
67  str += '=';
68 
69  }
70  return str;
71 }
72 
73 /* -------------------------------------------------------------------------
74  DECODE
75 ------------------------------------------------------------------------- */
76 auto Base64::decode(const std::string &str) -> ByteArray
77 {
78  static array<int, 256> base64DecodeArray =
79  {
80  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 00-0F */
81  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10-1F */
82  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 20-2F */
83  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 30-3F */
84  -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 40-4F */
85  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 50-5F */
86  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 60-6F */
87  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, /* 70-7F */
88  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80-8F */
89  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 90-9F */
90  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* A0-AF */
91  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* B0-BF */
92  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* C0-CF */
93  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* D0-DF */
94  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* E0-EF */
95  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* F0-FF */
96  };
97 
98  ByteArray data;
99  data.reserve(str.size() * 3);
100 
101  int space_idx = 0, phase;
102  int d, prev_d = 0;
103  unsigned char c;
104 
105  space_idx = 0;
106  phase = 0;
107 
108  for (size_t i = 0; i < str.size(); i++)
109 {
110  d = base64DecodeArray[(int)str[i]];
111 
112  if (d != -1)
113  {
114  switch (phase)
115  {
116  case 0:
117  ++phase;
118  break;
119  case 1:
120  c = ((prev_d << 2) | ((d & 0x30) >> 4));
121  data.push_back(c);
122  ++phase;
123  break;
124  case 2:
125  c = (((prev_d & 0xf) << 4) | ((d & 0x3c) >> 2));
126  data.push_back(c);
127  ++phase;
128  break;
129  case 3:
130  c = (((prev_d & 0x03) << 6) | d);
131  data.push_back(c);
132  phase = 0;
133  break;
134  }
135  prev_d = d;
136  }
137  }
138  return data;
139 }
Definition: RWMutex.hpp:4
Package of libraries.
Definition: library.hpp:84
Binary data class.
Definition: ByteArray.hpp:30
Top level namespace of products built from samchon.
Definition: ByteArray.hpp:7