Samchon Framework for CPP  1.0.0
Base64.hpp
1 #pragma once
2 
3 #include <string>
4 #include <array>
5 
6 #include <samchon/ByteArray.hpp>
7 
8 namespace samchon
9 {
10 namespace library
11 {
26  class Base64
27  {
28  public:
36  template <typename Container>
37  static auto encode(const Container &byte_array) -> std::string
38  {
39  static const std::array<char, 64> BASE64_CHAR_ARRAY =
40  {
41  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
42  'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
43  'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
44  'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
45  'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
46  'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
47  'w', 'x', 'y', 'z', '0', '1', '2', '3',
48  '4', '5', '6', '7', '8', '9', '+', '/'
49  };
50 
51  unsigned char *bytes = (unsigned char*)byte_array.data();
52  std::string str;
53  str.reserve(byte_array.size() * 4);
54 
55  long long left_size = (long long)byte_array.size();
56 
57  size_t i = 0;
58  size_t j = 0;
59  std::array<unsigned char, 3> input;
60  std::array<unsigned char, 4> output;
61 
62  while (left_size--)
63  {
64  input[i++] = *(bytes++);
65  if (i == 3)
66  {
67  output[0] = (input[0] & 0xfc) >> 2;
68  output[1] = ((input[0] & 0x03) << 4) + ((input[1] & 0xf0) >> 4);
69  output[2] = ((input[1] & 0x0f) << 2) + ((input[2] & 0xc0) >> 6);
70  output[3] = input[2] & 0x3f;
71 
72  for (i = 0; (i < 4); i++)
73  str += BASE64_CHAR_ARRAY[output[i]];
74  i = 0;
75  }
76  }
77 
78  if (i)
79  {
80  for (j = i; j < 3; j++)
81  input[j] = '\0';
82 
83  output[0] = (input[0] & 0xfc) >> 2;
84  output[1] = ((input[0] & 0x03) << 4) + ((input[1] & 0xf0) >> 4);
85  output[2] = ((input[1] & 0x0f) << 2) + ((input[2] & 0xc0) >> 6);
86  output[3] = input[2] & 0x3f;
87 
88  for (j = 0; (j < i + 1); j++)
89  str += BASE64_CHAR_ARRAY[output[j]];
90 
91  while ((i++ < 3))
92  str += '=';
93 
94  }
95  return str;
96  };
97 
107  static auto decode(const std::string &str) -> ByteArray
108  {
109  static const std::array<int, 256> BASE64_DECODE_ARRAY =
110  {
111  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 00-0F */
112  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 10-1F */
113  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, /* 20-2F */
114  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, /* 30-3F */
115  -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, /* 40-4F */
116  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1, /* 50-5F */
117  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, /* 60-6F */
118  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1, /* 70-7F */
119  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80-8F */
120  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 90-9F */
121  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* A0-AF */
122  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* B0-BF */
123  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* C0-CF */
124  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* D0-DF */
125  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* E0-EF */
126  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 /* F0-FF */
127  };
128 
129  ByteArray data;
130  data.reserve(str.size() * 3);
131 
132  int space_idx = 0, phase;
133  int d, prev_d = 0;
134  unsigned char c;
135 
136  space_idx = 0;
137  phase = 0;
138 
139  for (size_t i = 0; i < str.size(); i++)
140  {
141  d = BASE64_DECODE_ARRAY[(int)str[i]];
142 
143  if (d != -1)
144  {
145  switch (phase)
146  {
147  case 0:
148  ++phase;
149  break;
150  case 1:
151  c = ((prev_d << 2) | ((d & 0x30) >> 4));
152  data.push_back(c);
153  ++phase;
154  break;
155  case 2:
156  c = (((prev_d & 0xf) << 4) | ((d & 0x3c) >> 2));
157  data.push_back(c);
158  ++phase;
159  break;
160  case 3:
161  c = (((prev_d & 0x03) << 6) | d);
162  data.push_back(c);
163  phase = 0;
164  break;
165  }
166  prev_d = d;
167  }
168  }
169  return data;
170  };
171  };
172 };
173 };
static auto encode(const Container &byte_array) -> std::string
Encode from binary data to base64-string.
Definition: Base64.hpp:37
static auto decode(const std::string &str) -> ByteArray
Decode from base64-string to binary data.
Definition: Base64.hpp:107
Binary data class.
Definition: ByteArray.hpp:29
Utility class for base64 format&#39;s en-decoding.
Definition: Base64.hpp:26