RDK Documentation (Open Sourced RDK Components)
_base64.cpp
Go to the documentation of this file.
1 /*
2  * If not stated otherwise in this file or this component's license file the
3  * following copyright and licenses apply:
4  *
5  * Copyright 2018 RDK Management
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18 */
19 
20 /**
21  * @file _base64.cpp
22  * @brief optimized pair of base64 encode/decode implementations
23  */
24 
25 
26 #include "_base64.h"
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdio.h>
30 
31 /**
32  * @brief convert blob of binary data to ascii base64-encoded equivalent
33  * @retval pointer to malloc'd cstring containing base64 encoded version of string
34  * @retval NULL if insufficient memory to allocate base64-encoded copy
35  * @note caller responsible for freeing returned cstring
36  */
37 char *base64_Encode(const unsigned char *src, size_t len)
38 {
39  static const char *mBase64IndexToChar =
40  "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
41  "abcdefghijklmnopqrstuvwxyz"
42  "0123456789"
43  "+/"; // note: some older implementations use "-" instead of "/"
44  size_t outLen = ((len + 2) / 3) * 4;
45  char *outData = (char *)malloc(1 + outLen);
46  if( outData )
47  { // aaaaaa aabbbb bbbbcc cccccc
48  char *dst = outData;
49  outData[outLen] = 0x00;
50  for (;;)
51  {
52  if (len == 0) break;
53  int in0 = src[0] >> 2;
54  int in1 = (src[0] & 0x3) << 4;
55  dst[0] = mBase64IndexToChar[in0];
56  dst[1] = mBase64IndexToChar[in1];
57  len--;
58  if (len == 0)
59  {
60  dst[2] = '=';
61  dst[3] = '=';
62  break;
63  }
64  in1 |= (src[1] >> 4);
65  int in2 = (src[1] & 0xf) << 2;
66  dst[1] = mBase64IndexToChar[in1];
67  dst[2] = mBase64IndexToChar[in2];
68  len--;
69  if (len == 0)
70  {
71  dst[3] = '=';
72  break;
73  }
74  in2 |= src[2] >> 6;
75  int in3 = src[2] & 0x3f;
76  dst[2] = mBase64IndexToChar[in2];
77  dst[3] = mBase64IndexToChar[in3];
78  len--;
79  src += 3;
80  dst += 4;
81  }
82  }
83  return outData;
84 }
85 
86 
87 /**
88  * @brief decode base64 encoded data to binary equivalent
89  * @retval return value from base64_Decode value
90  */
91 unsigned char *base64_Decode(const char *src, size_t *len, size_t srcLen)
92 {
93  static const signed char mBase64CharToIndex[256] =
94  {
95  /*
96  Generated using:
97 
98 
99  static int CodeToIndex( char c )
100  {
101  if (c >= 'A' && c <= 'Z') return c - 'A';
102  if (c >= 'a' && c <= 'z') return (c - 'a') + 26;
103  if (c >= '0' && c <= '9') return (c - '0') + 26 * 2;
104  if (c == '+') return 62;
105  if (c == '-') return 63;
106  if (c == '/') return 63; // new
107  return -1; // error
108  }
109  */
110  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
111  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
112  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, 63, -1, 63,
113  52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
114  -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
115  15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
116  -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
117  41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1,
118  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
119  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
120  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
121  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
122  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
123  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
124  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
125  -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
126  };
127  size_t numChars = (srcLen * 3) / 4; // initially round up to nearest 4 bytes, avoid losing precision
128  unsigned char *outData = (unsigned char *)malloc(numChars);
129  size_t outSize = 0; // output size
130  if (outData)
131  {
132  // memset(outData, 0x00, numChars); // not-needed
133  unsigned char *dst = outData;
134  const char *finish = src + srcLen;
135  while (src < finish)
136  { // aaaaaa aabbbb bbbbcc cccccc
137  int data0 = mBase64CharToIndex[(unsigned char)src[0]];
138  int data1 = mBase64CharToIndex[(unsigned char)src[1]];
139  int data2 = mBase64CharToIndex[(unsigned char)src[2]];
140  int data3 = mBase64CharToIndex[(unsigned char)src[3]];
141  *dst++ = (data0 << 2) | (data1 >> 4);
142  if (data2 < 0)
143  {
144  outSize++;
145  break;
146  }
147  *dst++ = (data1 << 4) | (data2 >> 2);
148  if (data3 < 0)
149  {
150  outSize += 2;
151  break;
152  }
153  *dst++ = (data2 << 6) | (data3);
154  src += 4;
155  outSize += 3;
156  }
157  *len = outSize;
158  }
159  else
160  { // insufficient memory
161  *len = 0;
162  }
163  return outData;
164 }
165 
166 /**
167  * @brief decode base64 encoded data to binary equivalent
168  * @retval pointer to malloc'd memory containing decoded binary data
169  * @retval NULL if insufficient memory to allocate base64-decoded data
170  * @note caller responsible for freeing returned data
171  */
172 unsigned char *base64_Decode(const char *src, size_t *len)
173 {
174  return base64_Decode(src, len, strlen(src));
175 }
176 /**
177  * @}
178  */
base64_Encode
char * base64_Encode(const unsigned char *src, size_t len)
convert blob of binary data to ascii base64-encoded equivalent
Definition: _base64.cpp:37
_base64.h
base64 source Encoder/Decoder
base64_Decode
unsigned char * base64_Decode(const char *src, size_t *len, size_t srcLen)
decode base64 encoded data to binary equivalent
Definition: _base64.cpp:91