comparison C++/Base64.h @ 238:b97d75a78e22

Add Base64, base64 encoding and decoding
author David Demelier <markand@malikania.fr>
date Thu, 11 Sep 2014 17:21:51 +0200
parents
children a9883eeb9757
comparison
equal deleted inserted replaced
237:887d43215b90 238:b97d75a78e22
1 /*
2 * Base64.h -- base64 encoding and decoding
3 *
4 * Copyright (c) 2013, 2014 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #ifndef _BASE_64_H_
20 #define _BASE_64_H_
21
22 /**
23 * @file Base64.h
24 * @brief Base64 encoding and decoding
25 */
26
27 #include <stdexcept>
28 #include <string>
29
30 /**
31 * @class Base64
32 * @brief Encode and decode Base64 data
33 */
34 class Base64 {
35 public:
36 /**
37 * Get the base 64 character from the 6-bits value.
38 *
39 * @param value the value
40 */
41 static char lookup(int value) noexcept;
42
43 /**
44 * Get the integer value from the base 64 character.
45 *
46 * @param ch the base64 character
47 */
48 static int rlookup(char ch);
49
50 /**
51 * Encode the input to the output. Requirements:
52 * InputIt must be InputIterator
53 * OutputIt must be OutputIterator
54 *
55 * @param input the beginning
56 * @param end the end of the data
57 * @output the output destination
58 */
59 template <typename InputIt, typename OutputIt>
60 static void encode(InputIt input, InputIt end, OutputIt output)
61 {
62 while (input != end) {
63 char inputbuf[3] = { 0, 0, 0 };
64 int count;
65
66 for (count = 0; count < 3 && input != end; ++count)
67 inputbuf[count] = *input++;
68
69 *output++ = lookup(inputbuf[0] >> 2 & 0x3f);
70 *output++ = lookup(inputbuf[0] << 4 & 0x3f | inputbuf[1] >> 4 & 0x0f);
71 *output++ = (count < 2) ? '=' : lookup(inputbuf[1] << 2 & 0x3c | inputbuf[2] >> 6 & 0x03);
72 *output++ = (count < 3) ? '=' : lookup(inputbuf[2] & 0x3f);
73 }
74 }
75
76 /**
77 * Decode the input to the output. Requirements:
78 * InputIt must be InputIterator
79 * OutputIt must be OutputIterator
80 *
81 * @param input the beginning
82 * @param end the end of the data
83 * @output the output destination
84 * @throw std::invalid_argument on bad base64 string
85 */
86 template <typename InputIt, typename OutputIt>
87 static void decode(InputIt input, InputIt end, OutputIt output)
88 {
89 while (input != end) {
90 char inputbuf[4] = { 0, 0, 0, 0 };
91 int count;
92
93 for (count = 0; count < 4 && input != end; ++count) {
94 inputbuf[count] = (*input == '=') ? '=' : rlookup(*input);
95 input++;
96 }
97
98 if (count != 4)
99 throw std::invalid_argument("truncated string");
100
101 *output++ = inputbuf[0] << 2 & 0xfc | inputbuf[1] >> 4 & 0x03;
102
103 if (inputbuf[2] != '=')
104 *output++ = inputbuf[1] << 4 & 0xf0 | inputbuf[2] >> 2 & 0x0f;
105 if (inputbuf[3] != '=')
106 *output++ = inputbuf[2] << 6 & 0xc0 | inputbuf[3] & 0x3f;
107 }
108 }
109
110 /**
111 * Encode a string.
112 *
113 * @param input the input string
114 * @return the base64 formatted string
115 */
116 static std::string encode(const std::string &input);
117
118 /**
119 * Decode a string.
120 *
121 * @param input the base64 formatted string
122 * @return the original string
123 * @throw std::invalid_argument on bad base64 string
124 */
125 static std::string decode(const std::string &input);
126 };
127
128 #endif // !_BASE_64_H_