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