base64.cc Source File

- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
base64.cc
Go to the documentation of this file.
1 #include "osl/misc/base64.h"
2 #include "osl/stl/vector.h"
3 #include <boost/foreach.hpp>
4
5 std::string osl::misc::
6 base64Encode(boost::dynamic_bitset<> src)
7 {
8 if (src.empty())
9 return "";
10
11 const size_t bits_to_add = 6 - src.size()%6;
12 if (bits_to_add < 6)
13 {
14 for (size_t i=0; i<bits_to_add; ++i)
15 {
16 src.push_back(0ul); // this appends to the most significant bit
17 src <<= 1; // Instead, append to the least significant bit
18 }
19 }
20 assert(src.size()%6 == 0);
21 assert(src.size()/6 > 0);
22
23 vector<char> dst(src.size()/6, 0);
24 const boost::dynamic_bitset<> mask(src.size(), 63ul);
25 for (size_t i=0; i<dst.size(); ++i)
26 {
27 const unsigned long c = ((src >> i*6) & mask).to_ulong();
28 assert (c <= 63);
29 if (/*0 <= c &&*/ c <= 25) // A..Z
30 dst[dst.size()-1-i] = static_cast<char>(c+65);
31 else if (26 <= c && c <= 51) // a..z
32 dst[dst.size()-1-i] = static_cast<char>(c+97-26);
33 else if (52 <= c && c <= 61) // 0..9
34 dst[dst.size()-1-i] = static_cast<char>(c+48-52);
35 else if (c == 62)
36 dst[dst.size()-1-i] = '-'; // for URL instread of '+'
37 else if (c == 63)
38 dst[dst.size()-1-i] = '_'; // for URL instread of '/'
39 else
40 {
41 assert(false);
42 return "";
43 }
44 }
45
46 const size_t char_to_add = 4 - dst.size()%4;
47 if (char_to_add < 4)
48 {
49 for (size_t i=0; i<char_to_add; ++i)
50 dst.push_back('=');
51 }
52
53 return std::string(dst.begin(), dst.end());
54 }
55
56 boost::dynamic_bitset<> osl::misc::
57 base64Decode(std::string src)
58 {
59 if (src.empty() || src.size()%4 != 0)
60 return boost::dynamic_bitset<>(0);
61
62 {
63 int count = 0;
64 while (src[src.size()-1] == '=')
65 {
66 src.erase(src.end()-1);
67 ++count;
68 }
69 if (count >= 4)
70 return boost::dynamic_bitset<>(0);
71 }
72
73 const size_t dst_size = src.size()*6;
74 const size_t redundant = dst_size%8;
75 boost::dynamic_bitset<> dst(dst_size, 0ul);
76 BOOST_FOREACH(char c, src)
77 {
78 unsigned long tmp = 0;
79 if (48 <= c && c <= 48+9) // 0..9
80 tmp = c -48+52;
81 else if (65 <= c && c <= 65+25) // A..Z
82 tmp = c - 65;
83 else if (97 <= c && c <= 97+25) // a..z
84 tmp = c -97+26;
85 else if (c == '-')
86 tmp = 62;
87 else if (c == '_')
88 tmp = 63;
89 else
90 {
91 assert(false);
92 return boost::dynamic_bitset<>(0);
93 }
94 assert(/*0 <= tmp &&*/ tmp <= 63);
95 const boost::dynamic_bitset<> mask(dst_size, tmp);
96 dst = (dst << 6) | mask;
97 }
98 if (redundant > 0)
99 {
100 dst >>= redundant;
101 dst.resize(dst.size()-redundant);
102 }
103 return dst;
104 }
105 // ;;; Local Variables:
106 // ;;; mode:c++
107 // ;;; c-basic-offset:2
108 // ;;; End: