Firmware SDK
 All Data Structures Functions Variables Typedefs Enumerations Enumerator Groups Pages
bc_base64.c
1 #include <bc_base64.h>
2 
3 const char bc_b64_alphabet[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
4 
5 static uint8_t bc_base64_lookup(char c);
6 
7 bool bc_base64_encode(char *output, size_t *output_length, uint8_t *input, size_t input_length)
8 {
9  size_t i = 0, j = 0;
10  size_t encode_length = 0;
11  uint8_t a3[3];
12  uint8_t a4[4];
13 
14  for (; input_length != 0; input_length--)
15  {
16  a3[i++] = *(input++);
17  if (i == 3)
18  {
19  a4[0] = (uint8_t) ((a3[0] & 0xfc) >> 2);
20  a4[1] = (uint8_t) (((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4));
21  a4[2] = (uint8_t) (((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6));
22  a4[3] = (uint8_t) (a3[2] & 0x3f);
23 
24  for (i = 0; i < 4; i++)
25  {
26  output[encode_length++] = bc_b64_alphabet[a4[i]];
27  if (encode_length > *output_length)
28  {
29  return false;
30  }
31  }
32 
33  i = 0;
34  }
35  }
36 
37  if (i != 0)
38  {
39  for (j = i; j < 3; j++)
40  {
41  a3[j] = 0x00;
42  }
43 
44  a4[0] = (uint8_t) ((a3[0] & 0xfc) >> 2);
45  a4[1] = (uint8_t) (((a3[0] & 0x03) << 4) + ((a3[1] & 0xf0) >> 4));
46  a4[2] = (uint8_t) (((a3[1] & 0x0f) << 2) + ((a3[2] & 0xc0) >> 6));
47  a4[3] = (uint8_t) (a3[2] & 0x3f);
48 
49  for (j = 0; j < (i + 1); j++)
50  {
51  output[encode_length++] = bc_b64_alphabet[a4[j]];
52  if (encode_length > *output_length)
53  {
54  return false;
55  }
56 
57  }
58 
59  while (i++ < 3)
60  {
61  output[encode_length++] = '=';
62  if (encode_length > *output_length)
63  {
64  return false;
65  }
66  }
67  }
68 
69  output[encode_length] = 0x00;
70 
71  *output_length = encode_length;
72 
73  return true;
74 }
75 
76 bool bc_base64_decode(uint8_t *output, size_t *output_length, char *input, size_t input_length)
77 {
78  size_t i = 0, j = 0;
79  size_t decode_length = 0;
80  uint8_t a3[3];
81  uint8_t a4[4];
82 
83  for (; input_length != 0; input_length--)
84  {
85  if (*input == '=')
86  {
87  break;
88  }
89 
90  a4[i++] = (uint8_t) *(input++);
91  if (i == 4)
92  {
93  for (i = 0; i < 4; i++)
94  {
95  a4[i] = bc_base64_lookup(a4[i]);
96  }
97 
98  a3[0] = (uint8_t) ((a4[0] << 2) + ((a4[1] & 0x30) >> 4));
99  a3[1] = (uint8_t) (((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2));
100  a3[2] = (uint8_t) (((a4[2] & 0x3) << 6) + a4[3]);
101 
102  for (i = 0; i < 3; i++)
103  {
104  output[decode_length++] = a3[i];
105  if (decode_length > *output_length)
106  {
107  return false;
108  }
109  }
110 
111  i = 0;
112  }
113  }
114 
115  if (i != 0)
116  {
117  for (j = i; j < 4; j++)
118  {
119  a4[j] = 0x00;
120  }
121 
122  for (j = 0; j < 4; j++)
123  {
124  a4[j] = bc_base64_lookup(a4[j]);
125  }
126 
127  a3[0] = (uint8_t) ((a4[0] << 2) + ((a4[1] & 0x30) >> 4));
128  a3[1] = (uint8_t) (((a4[1] & 0xf) << 4) + ((a4[2] & 0x3c) >> 2));
129  a3[2] = (uint8_t) (((a4[2] & 0x3) << 6) + a4[3]);
130 
131  for (j = 0; j < (i - 1); j++)
132  {
133  output[decode_length++] = a3[j];
134  if (decode_length > *output_length)
135  {
136  return false;
137  }
138  }
139  }
140 
141  output[decode_length] = 0x00;
142 
143  *output_length = decode_length;
144 
145  return true;
146 }
147 
149 {
150  size_t n = (int) length;
151  return (n + 2 - ((n + 2) % 3)) / 3 * 4;
152 }
153 
154 size_t bc_base64_calculate_decode_length(char *input, size_t length)
155 {
156  size_t i = 0;
157  size_t num_eq = 0;
158 
159  for (i = length - 1; input[i] == '='; i--)
160  {
161  num_eq++;
162  }
163 
164  return ((6 * length) / 8) - num_eq;
165 }
166 
167 static uint8_t bc_base64_lookup(char c)
168 {
169  if (c >= 'A' && c <= 'Z')
170  {
171  return (uint8_t) (c - 'A');
172  }
173  if (c >= 'a' && c <= 'z')
174  {
175  return (uint8_t) (c - 71);
176  }
177  if (c >= '0' && c <= '9')
178  {
179  return (uint8_t) (c + 4);
180  }
181  if (c == '+')
182  {
183  return 62;
184  }
185  if (c == '/')
186  {
187  return 63;
188  }
189  return (uint8_t) -1;
190 }
bool bc_base64_encode(char *output, size_t *output_length, uint8_t *input, size_t input_length)
BASE64 encode.
Definition: bc_base64.c:7
bool bc_base64_decode(uint8_t *output, size_t *output_length, char *input, size_t input_length)
BASE64 decode.
Definition: bc_base64.c:76
size_t bc_base64_calculate_decode_length(char *input, size_t length)
BASE64 Calculate decode length.
Definition: bc_base64.c:154
size_t bc_base64_calculate_encode_length(size_t length)
BASE64 Calculate encode length.
Definition: bc_base64.c:148