1db6254e3Simarom/*
2db6254e3Simarom   base64.cpp and base64.h
3db6254e3Simarom
4db6254e3Simarom   Copyright (C) 2004-2008 Ren� Nyffenegger
5db6254e3Simarom
6db6254e3Simarom   This source code is provided 'as-is', without any express or implied
7db6254e3Simarom   warranty. In no event will the author be held liable for any damages
8db6254e3Simarom   arising from the use of this software.
9db6254e3Simarom
10db6254e3Simarom   Permission is granted to anyone to use this software for any purpose,
11db6254e3Simarom   including commercial applications, and to alter it and redistribute it
12db6254e3Simarom   freely, subject to the following restrictions:
13db6254e3Simarom
14db6254e3Simarom   1. The origin of this source code must not be misrepresented; you must not
15db6254e3Simarom      claim that you wrote the original source code. If you use this source code
16db6254e3Simarom      in a product, an acknowledgment in the product documentation would be
17db6254e3Simarom      appreciated but is not required.
18db6254e3Simarom
19db6254e3Simarom   2. Altered source versions must be plainly marked as such, and must not be
20db6254e3Simarom      misrepresented as being the original source code.
21db6254e3Simarom
22db6254e3Simarom   3. This notice may not be removed or altered from any source distribution.
23db6254e3Simarom
24db6254e3Simarom   Ren� Nyffenegger rene.nyffenegger@adp-gmbh.ch
25db6254e3Simarom
26db6254e3Simarom*/
27db6254e3Simarom
28db6254e3Simarom#include "base64.h"
29db6254e3Simarom#include <iostream>
30db6254e3Simarom
31db6254e3Simaromstatic const std::string base64_chars =
32db6254e3Simarom             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
33db6254e3Simarom             "abcdefghijklmnopqrstuvwxyz"
34db6254e3Simarom             "0123456789+/";
35db6254e3Simarom
36db6254e3Simarom
37db6254e3Simaromstatic inline bool is_base64(unsigned char c) {
38db6254e3Simarom  return (isalnum(c) || (c == '+') || (c == '/'));
39db6254e3Simarom}
40db6254e3Simarom
41db6254e3Simaromstd::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
42db6254e3Simarom  std::string ret;
43db6254e3Simarom  int i = 0;
44db6254e3Simarom  int j = 0;
45db6254e3Simarom  unsigned char char_array_3[3];
46db6254e3Simarom  unsigned char char_array_4[4];
47db6254e3Simarom
48db6254e3Simarom  while (in_len--) {
49db6254e3Simarom    char_array_3[i++] = *(bytes_to_encode++);
50db6254e3Simarom    if (i == 3) {
51db6254e3Simarom      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
52db6254e3Simarom      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
53db6254e3Simarom      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
54db6254e3Simarom      char_array_4[3] = char_array_3[2] & 0x3f;
55db6254e3Simarom
56db6254e3Simarom      for(i = 0; (i <4) ; i++)
57db6254e3Simarom        ret += base64_chars[char_array_4[i]];
58db6254e3Simarom      i = 0;
59db6254e3Simarom    }
60db6254e3Simarom  }
61db6254e3Simarom
62db6254e3Simarom  if (i)
63db6254e3Simarom  {
64db6254e3Simarom    for(j = i; j < 3; j++)
65db6254e3Simarom      char_array_3[j] = '\0';
66db6254e3Simarom
67db6254e3Simarom    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
68db6254e3Simarom    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
69db6254e3Simarom    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
70db6254e3Simarom    char_array_4[3] = char_array_3[2] & 0x3f;
71db6254e3Simarom
72db6254e3Simarom    for (j = 0; (j < i + 1); j++)
73db6254e3Simarom      ret += base64_chars[char_array_4[j]];
74db6254e3Simarom
75db6254e3Simarom    while((i++ < 3))
76db6254e3Simarom      ret += '=';
77db6254e3Simarom
78db6254e3Simarom  }
79db6254e3Simarom
80db6254e3Simarom  return ret;
81db6254e3Simarom
82db6254e3Simarom}
83db6254e3Simarom
84db6254e3Simaromstd::string base64_decode(std::string const& encoded_string) {
85db6254e3Simarom  int in_len = encoded_string.size();
86db6254e3Simarom  int i = 0;
87db6254e3Simarom  int j = 0;
88db6254e3Simarom  int in_ = 0;
89db6254e3Simarom  unsigned char char_array_4[4], char_array_3[3];
90db6254e3Simarom  std::string ret;
91db6254e3Simarom
92db6254e3Simarom  while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
93db6254e3Simarom    char_array_4[i++] = encoded_string[in_]; in_++;
94db6254e3Simarom    if (i ==4) {
95db6254e3Simarom      for (i = 0; i <4; i++)
96db6254e3Simarom        char_array_4[i] = base64_chars.find(char_array_4[i]);
97db6254e3Simarom
98db6254e3Simarom      char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
99db6254e3Simarom      char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
100db6254e3Simarom      char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
101db6254e3Simarom
102db6254e3Simarom      for (i = 0; (i < 3); i++)
103db6254e3Simarom        ret += char_array_3[i];
104db6254e3Simarom      i = 0;
105db6254e3Simarom    }
106db6254e3Simarom  }
107db6254e3Simarom
108db6254e3Simarom  if (i) {
109db6254e3Simarom    for (j = i; j <4; j++)
110db6254e3Simarom      char_array_4[j] = 0;
111db6254e3Simarom
112db6254e3Simarom    for (j = 0; j <4; j++)
113db6254e3Simarom      char_array_4[j] = base64_chars.find(char_array_4[j]);
114db6254e3Simarom
115db6254e3Simarom    char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
116db6254e3Simarom    char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
117db6254e3Simarom    char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
118db6254e3Simarom
119db6254e3Simarom    for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
120db6254e3Simarom  }
121db6254e3Simarom
122db6254e3Simarom  return ret;
123db6254e3Simarom}