In README.md, mention exceptions for all overloads.
[cppcodec.git] / README.md
1 # cppcodec
2
3 Header-only C++11 library to encode/decode base64 (standard, URL-safe),
4 base32 (RFC 4648, Crockford) and hex (a.k.a. base16). MIT licensed with
5 consistent, flexible API. Supports raw pointers, `std::string` and
6 (templated) character vectors without unnecessary allocations.
7
8
9
10 # Usage
11
12 1. Import cppcodec into your project (copy, git submodule, etc.)
13 2. Add the cppcodec root directory to your build system's list of include directories
14 3. Include headers and start using the API.
15
16 Since cppcodec is a header-only library, no extra build step is needed.
17 Alternatively, you can install the headers and build extra tools/tests with CMake.
18
19
20
21 # Variants
22
23 A number of codec variants exist for base64 and base32, defining different alphabets
24 or specifying the use of padding and line breaks in different ways. cppcodec is designed
25 to let you make a conscious choice about which one you're using, but assumes you will
26 mostly stick to a single one.
27
28 cppcodec's approach is to implement encoding/decoding algorithms in different namespaces
29 (e.g. `cppcodec::base64_rfc4648`) and in addition to the natural headers, also offer
30 convenience headers to define a shorthand alias (e.g. `base64`) for one of the variants.
31
32 Here is an expected standard use of cppcodec:
33
34 ```C++
35 #include <cppcodec/base32_default_crockford.hpp>
36 #include <cppcodec/base64_default_rfc4648.hpp>
37 #include <iostream>
38
39 int main() {
40    std::vector<uint8_t> decoded = base64::decode("YW55IGNhcm5hbCBwbGVhc3VyZQ==");
41    std::cout << "decoded size (\"any carnal pleasure\"): " << decoded.size() << '\n';
42    std::cout << base32::encode(decoded) << std::endl; // "C5Q7J833C5S6WRBC41R6RSB1EDTQ4S8"
43    return 0;
44 }
45 ```
46
47 If possible, avoid including "default" headers in other header files.
48
49 Non-aliasing headers omit the "default" part, e.g. `<cppcodec/base64_rfc4648.hpp>`
50 or `<cppcodec/hex_lower.hpp>`. Currently supported variants are:
51
52 ### base64
53
54 * `base64_rfc4648` uses the PEM/MIME/UTF-7 alphabet, that is (in order)
55   A-Z, a-z, 0-9 plus characters '+' and '/'. This is what's usually considered
56   the "standard base64" that you see everywhere and requires padding ('=') but
57   no line breaks. Whitespace and other out-of-alphabet symbols are regarded as
58   a parse error.
59 * `base64_url` is the same as `base64_rfc4648` (and defined in the same RFC)
60   but uses '-' (minus) and '_' (underscore) as special characters instead of
61   '+' and '/'. This is safe to use for URLs and file names. Padding with '=' is
62   still required, look for a future `base64_url_unpadded` variant if you want
63   to do without.
64
65 ### base32
66
67 All base32 variants encode 5 bits as one (8-bit) character, which results in
68 an encoded length of roughly 160% (= 8/5). Their selling point is mainly
69 case-insensitive decoding, no special characters and alphabets that can be
70 communicated via phone.
71
72 * `base32_rfc4648` implements the popular, standardized variant defined in
73   RFC 4648. It uses the full upper-case alphabet A-Z for the first 26 values
74   and the digit characters 2-7 for the last ten. Padding with '=' is required
75   and makes the encoded string a multiple of 8 characters. The codec accepts
76   no invalid symbols, so if you want to let the user enter base32 data then
77   consider replacing numbers '0', '1' and '8' with 'O', 'I' and 'B' on input.
78 * `base32_crockford` implements [Crockford base32](http://www.crockford.com/wrmg/base32.html).
79   It's less widely used than the RFC 4648 alphabet, but offers a more carefully
80   picked alphabet and also defines decoding similar characters 'I', 'i', 'L'
81   'l' as '1' plus 'O' and 'o' as '0' so no care is required for user input.
82   Crockford base32 does not use '=' padding. Checksums are not implemented.
83   Note that the specification is ambiguous about whether to pad bit quintets to
84   the left or to the right, i.e. whether the codec is a place-based single number
85   encoding system or a concatenative iterative stream encoder. This codec variant
86   picks the streaming interpretation and thus zero-pads on the right. (See
87   http://merrigrove.blogspot.ca/2014/04/what-heck-is-base64-encoding-really.html
88   for a detailed discussion of the issue.)
89
90 ### hex
91
92 * `hex_upper` outputs upper-case letters and accepts lower-case as well.
93   This is an octet-streaming codec variant and for decoding, requires an even
94   number of input symbols. In other words, don't try to decode (0x)"F",
95   (0x)"10F" etc. with this variant, use a place-based single number codec
96   instead if you want to do this. Also, you are expected to prepend and remove
97   a "0x" prefix externally as it won't be generated when encoding / will be
98   rejected when decoding.
99 * `hex_lower` outputs lower-case letters and accepts upper-case as well.
100   Similar to `hex_upper`, it's stream-based (no odd symbol lengths) and does
101   not deal with "0x" prefixes.
102
103
104
105 # API
106
107 All codecs expose the same API. In the below documentation, replace `<codec>` with a
108 default alias such as `base64`, `base32` or `hex`, or with the full namespace such as
109 `cppcodec::base64_rfc4648` or `cppcodec::base32_crockford`.
110
111 For templated parameters `T` and `Result`, you can use e.g. `std::vector<uint8_t>`,
112 `std::string` or anything that supports:
113 * `.data()` and `.size()` for `T` (read-only) template parameters,
114 * for `Result` template parameters, also `.reserve(size_t)`, `.resize(size_t)`
115   and `.push_back([uint8_t|char])`.
116
117 It's possible to support types lacking these functions, consult the code directly if you need this.
118
119
120 ### Encoding
121
122 ```C++
123 // Convenient version, returns an std::string.
124 std::string <codec>::encode(const [uint8_t|char]* binary, size_t binary_size);
125 std::string <codec>::encode(const T& binary);
126
127 // Convenient version with templated result type.
128 Result <codec>::encode<Result>(const [uint8_t|char]* binary, size_t binary_size);
129 Result <codec>::encode<Result>(const T& binary);
130
131 // Reused result container version. Resizes encoded_result before writing to it.
132 void <codec>::encode(Result& encoded_result, const [uint8_t|char]* binary, size_t binary_size);
133 void <codec>::encode(Result& encoded_result, const T& binary);
134 ```
135
136 Encode binary data into an encoded (base64/base32/hex) string.
137 Won't throw by itself, but the result type might throw on `.resize()`.
138
139 ```C++
140 size_t <codec>::encode(char* encoded_result, size_t encoded_buffer_size, const [uint8_t|char]* binary, size_t binary_size) noexcept;
141 size_t <codec>::encode(char* encoded_result, size_t encoded_buffer_size, const T& binary) noexcept;
142 ```
143
144 Encode binary data into pre-allocated memory with a buffer size of
145 `<codec>::encoded_size(binary_size)` or larger.
146
147 Returns the byte size of the encoded string excluding null termination,
148 which is equal to `<codec>::encoded_size(binary_size)`.
149
150 If `encoded_buffer_size` is larger than required, a single null termination character (`'\0'`)
151 is written after the last encoded character. The `encoded_size()` function ensures that the required
152 buffer size is large enough to hold the padding required for the respective codec variant.
153 Provide a buffer of size `encoded_size() + 1` to make it a null-terminated C string.
154
155 Calls abort() if `encoded_buffer_size` is insufficient. (That way, the function can remain `noexcept`
156 rather than throwing on an entirely avoidable error condition.)
157
158 ```C++
159 size_t <codec>::encoded_size(size_t binary_size) noexcept;
160 ```
161
162 Calculate the (exact) length of the encoded string based on binary size,
163 excluding null termination but including padding (if specified by the codec variant).
164
165
166 ### Decoding
167
168 ```C++
169 // Convenient version, returns an std::vector<uint8_t>.
170 std::vector<uint8_t> <codec>::decode(const char* encoded, size_t encoded_size);
171 std::vector<uint8_t> <codec>::decode(const T& encoded);
172
173 // Convenient version with templated result type.
174 Result <codec>::decode<Result>(const char* encoded, size_t encoded_size);
175 Result <codec>::decode<Result>(const T& encoded);
176
177 // Reused result container version. Resizes binary_result before writing to it.
178 void <codec>::decode(Result& binary_result, const char* encoded, size_t encoded_size);
179 void <codec>::decode(Result& binary_result, const T& encoded);
180 ```
181
182 Decode an encoded (base64/base32/hex) string into a binary buffer.
183
184 Throws a cppcodec::parse_error exception (inheriting from std::domain_error)
185 if the input data does not conform to the codec variant specification.
186 Also, the result type might throw on `.resize()`.
187
188 ```C++
189 size_t <codec>::decode([uint8_t|char]* binary_result, size_t binary_buffer_size, const char* encoded, size_t encoded_size);
190 size_t <codec>::decode([uint8_t|char]* binary_result, size_t binary_buffer_size, const T& encoded);
191 ```
192
193 Decode an encoded string into pre-allocated memory with a buffer size of
194 `<codec>::decoded_max_size(encoded_size)` or larger.
195
196 Returns the byte size of the decoded binary data, which is less or equal to
197 `<codec>::decoded_max_size(encoded_size)`.
198
199 Calls abort() if `binary_buffer_size` is insufficient, for consistency with encode().
200 Throws a cppcodec::parse_error exception (inheriting from std::domain_error)
201 if the input data does not conform to the codec variant specification.
202
203 ```C++
204 size_t <codec>::decoded_max_size(size_t encoded_size) noexcept;
205 ```
206
207 Calculate the maximum size of the decoded binary buffer based on the encoded string length.
208
209 If the codec variant does not allow padding or whitespace / line breaks,
210 the maximum decoded size will be the exact decoded size.
211
212 If the codec variant allows padding or whitespace / line breaks, the actual decoded size
213 might be smaller. If you're using the pre-allocated memory result call, make sure to take
214 its return value (the actual decoded size) into account.