Mercurial > code
comparison C++/modules/Base64/base64.h @ 485:898d8b29a4f1
Switch to lowercase filenames
author | David Demelier <markand@malikania.fr> |
---|---|
date | Thu, 12 Nov 2015 21:53:36 +0100 |
parents | C++/modules/Base64/Base64.h@3f29e6c05983 |
children |
comparison
equal
deleted
inserted
replaced
484:3ee3f3e53ee3 | 485:898d8b29a4f1 |
---|---|
1 /* | |
2 * Base64.h -- base64 encoding and decoding | |
3 * | |
4 * Copyright (c) 2013-2015 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 namespace base64 { | |
31 | |
32 /** | |
33 * Get the base 64 character from the 6-bits value. | |
34 * | |
35 * @pre value must be valid | |
36 * @param value the value | |
37 */ | |
38 unsigned char lookup(unsigned int value) noexcept; | |
39 | |
40 /** | |
41 * Get the integer value from the base 64 character. | |
42 * | |
43 * @pre ch must be a valid base 64 character but not '=' | |
44 * @param ch the base64 character | |
45 */ | |
46 unsigned int rlookup(unsigned char ch); | |
47 | |
48 /** | |
49 * Check if the given character is a valid base 64 character. | |
50 * | |
51 * @param char the character | |
52 * @return true if the character is valid | |
53 */ | |
54 bool isValid(unsigned char) noexcept; | |
55 | |
56 /** | |
57 * Encode the input to the output. Requirements: | |
58 * InputIt must be InputIterator | |
59 * OutputIt must be OutputIterator | |
60 * | |
61 * @param input the beginning | |
62 * @param end the end of the data | |
63 * @param output the output destination | |
64 * @return output | |
65 */ | |
66 template <typename InputIt, typename OutputIt> | |
67 OutputIt encode(InputIt input, InputIt end, OutputIt output) | |
68 { | |
69 while (input != end) { | |
70 char inputbuf[3] = { 0, 0, 0 }; | |
71 int count; | |
72 | |
73 for (count = 0; count < 3 && input != end; ++count) { | |
74 inputbuf[count] = *input++; | |
75 } | |
76 | |
77 *output++ = lookup(inputbuf[0] >> 2 & 0x3f); | |
78 *output++ = lookup((inputbuf[0] << 4 & 0x3f) | (inputbuf[1] >> 4 & 0x0f)); | |
79 *output++ = (count < 2) ? '=' : lookup((inputbuf[1] << 2 & 0x3c) | (inputbuf[2] >> 6 & 0x03)); | |
80 *output++ = (count < 3) ? '=' : lookup(inputbuf[2] & 0x3f); | |
81 } | |
82 | |
83 return output; | |
84 } | |
85 | |
86 /** | |
87 * Decode the input to the output. Requirements: | |
88 * InputIt must be InputIterator | |
89 * OutputIt must be OutputIterator | |
90 * | |
91 * @param input the beginning | |
92 * @param end the end of the data | |
93 * @param output the output destination | |
94 * @return output | |
95 * @throw std::invalid_argument on bad base64 string | |
96 */ | |
97 template <typename InputIt, typename OutputIt> | |
98 OutputIt decode(InputIt input, InputIt end, OutputIt output) | |
99 { | |
100 while (input != end) { | |
101 char inputbuf[4] = { -1, -1, -1, -1 }; | |
102 int count; | |
103 | |
104 for (count = 0; count < 4 && input != end; ++count) { | |
105 if (*input != '=') { | |
106 /* Check if the character is valid and get its value */ | |
107 if (isValid(*input)) { | |
108 inputbuf[count] = rlookup(*input); | |
109 } else { | |
110 throw std::invalid_argument{"invalid base64 string"}; | |
111 } | |
112 } else { | |
113 /* A base 64 string cannot start with "=" or "==" */ | |
114 if (count == 0 || count == 1) { | |
115 throw std::invalid_argument{"invalid or truncated base64 string"}; | |
116 } | |
117 } | |
118 | |
119 input++; | |
120 } | |
121 | |
122 if (count != 4) { | |
123 throw std::invalid_argument("truncated string"); | |
124 } | |
125 | |
126 *output++ = static_cast<unsigned char>(((inputbuf[0] << 2) & 0xfc) | ((inputbuf[1] >> 4) & 0x03)); | |
127 | |
128 if (inputbuf[2] != -1) { | |
129 *output++ = static_cast<unsigned char>(((inputbuf[1] << 4) & 0xf0) | ((inputbuf[2] >> 2) & 0x0f)); | |
130 } | |
131 if (inputbuf[3] != -1) { | |
132 /* "XY=Z" is not allowed */ | |
133 if (inputbuf[2] == -1) { | |
134 throw std::invalid_argument{"invalid base64 string"}; | |
135 } | |
136 | |
137 *output++ = static_cast<unsigned char>(((inputbuf[2] << 6) & 0xc0) | (inputbuf[3] & 0x3f)); | |
138 } | |
139 } | |
140 | |
141 return output; | |
142 } | |
143 | |
144 /** | |
145 * Encode a string. | |
146 * | |
147 * @param input the input string | |
148 * @return the base64 formatted string | |
149 */ | |
150 std::string encode(const std::string &input); | |
151 | |
152 /** | |
153 * Decode a string. | |
154 * | |
155 * @param input the base64 formatted string | |
156 * @return the original string | |
157 * @throw std::invalid_argument on bad base64 string | |
158 */ | |
159 std::string decode(const std::string &input); | |
160 | |
161 } // !base64 | |
162 | |
163 #endif // !_BASE_64_H_ |