cppcodec

repository·master·Indexed 20 days ago

https://github.com/tplgy/cppcodec

A header-only C++11 library providing encoding and decoding for Base64, Base32, and Hex variants as specified in RFC 4648. It includes support for various alphabets such as Crockford's Base32 and URL-safe Base64, offering APIs for returning new objects, reusing containers, or writing directly to pre-allocated raw buffers.

Tokens
2.3K
Snippets
6
Records
7
Agent score
22%

What's inside cppcodec

  1. Install and integrate cppcodec

    master

    cppcodec is a header-only C++11 library. To use it in your project:

    1. Import the library: Copy the source files into your project or add it as a git submodule.
    2. Configure include paths: Add the cppcodec root directory to your build system's include directories.
    3. Include headers: Include the specific codec header you need (e.g., #include <cppcodec/base64_rfc4648.hpp>) and start using the API.

    Since it is header-only, no separate compilation or linking step is required. You can also use CMake to install the headers or build the included tests and tools.

    // Example of including specific codec headers
    #include <cppcodec/base32_crockford.hpp>
    #include <cppcodec/base64_rfc4648.hpp>
  2. How to use cppcodec codecs

    master

    cppcodec implements different codec variants as distinct classes within the cppcodec namespace. Each variant has its own header file. To use a codec, include its specific header and access its encode and decode methods.

    Commonly, you will use std::vector<uint8_t> for decoded binary data and std::string for encoded text. The API supports raw pointers and templated character vectors without unnecessary allocations.

    #include <cppcodec/base32_crockford.hpp>
    #include <cppcodec/base64_rfc4648.hpp>
    #include <iostream>
    #include <vector>
    #include <cstdint>
    
    int main() {
      using base32 = cppcodec::base32_crockford;
      using base64 = cppcodec::base64_rfc4648;
    
      // Decoding a base64 string into a byte vector
      std::vector<uint8_t> decoded = base64::decode("YW55IGNhcm5hbCBwbGVhc3VyZQ==");
      std::cout << "decoded size: " << decoded.size() << '\n';
    
      // Encoding the byte vector into a base32 string
      std::cout << base32::encode(decoded) << std::endl; // "C5Q7J833C5S6WRBC41R6RSB1EDTQ4S8"
      return 0;
    }
  3. Calculate maximum decoding size

    master

    Use decoded_max_size to calculate the maximum possible size of the decoded binary buffer based on the encoded string length. This is useful for pre-allocating buffers.

    size_t <codec>::decoded_max_size(size_t encoded_size) noexcept;

    Note: If the codec variant allows padding or whitespace/line breaks, the actual decoded size might be smaller than the maximum. Always use the return value of the decoding function to determine the actual size of the data written to your buffer.

    size_t max_size = cppcodec::base64::decoded_max_size(encoded_string_size);
  4. Calculate required encoding size

    master

    Before encoding into a raw buffer, use encoded_size to determine the exact length of the encoded string (excluding null termination, but including padding if required by the codec variant).

    size_t <codec>::encoded_size(size_t binary_size) noexcept;

    size_t required_size = cppcodec::base64::encoded_size(input_binary_size);
  5. Use the encoding API

    master

    All codecs in cppcodec (e.g., base64, base32, hex) provide several ways to encode binary data into an encoded string.

    Supported Types

    For template parameters T (input) and Result (output), you can use types like std::vector<uint8_t> or std::string that support:

    • .data() and .size() for input types T.
    • .reserve(size_t), .resize(size_t), and .push_back([uint8_t|char]) for output types Result.

    Encoding Methods

    1. Convenient versions (returns a new object)

    These return a new instance of the requested type (e.g., std::string or a templated Result).

    • std::string <codec>::encode(const [uint8_t|char]* binary, size_t binary_size);
    • std::string <codec>::encode(const T& binary);
    • Result <codec>::encode<Result>(const [uint8_t|char]* binary, size_t binary_size);
    • Result <codec>::encode<Result>(const T& binary);

    2. Reused container version

    Resizes the provided encoded_result container before writing to it. This is useful for avoiding repeated allocations.

    • void <codec>::encode(Result& encoded_result, const [uint8_t|char]* binary, size_t binary_size);
    • void <codec>::encode(Result& encoded_result, const T& binary);

    3. Pre-allocated memory version (noexcept)

    Encodes directly into a raw buffer. This version is noexcept but will call abort() if the provided buffer is too small.

    • size_t <codec>::encode(char* encoded_result, size_t encoded_buffer_size, const [uint8_t|char]* binary, size_t binary_size) noexcept;
    • size_t <codec>::encode(char* encoded_result, size_t encoded_buffer_size, const T& binary) noexcept;

    To ensure a null-terminated C string, provide a buffer of size <codec>::encoded_size(binary_size) + 1.

    // Example: Encoding to a string
    std::string encoded = cppcodec::base64::encode(my_binary_data);
    
    // Example: Encoding into a pre-allocated buffer
    size_t required = cppcodec::base64::encoded_size(binary_size);
    std::vector<char> buffer(required + 1);
    size_t actual_size = cppcodec::base64::encode(buffer.data(), buffer.size(), binary_ptr, binary_size);
  6. Use the decoding API

    master

    Decodes an encoded string (base64, base32, or hex) back into a binary buffer. Note that decoding may throw a cppcodec::parse_error (inheriting from std::domain_error) if the input is invalid.

    Supported Types

    Input T must support .data() and .size(). Output Result must support .reserve(size_t), .resize(size_t), and .push_back([uint8_t|char]).

    Decoding Methods

    1. Convenient versions (returns a new object)

    • std::vector<uint8_t> <codec>::decode(const char* encoded, size_t encoded_size);
    • std::vector<uint8_t> <codec>::decode(const T& encoded);
    • Result <codec>::decode<Result>(const char* encoded, size_t encoded_size);
    • Result <codec>::decode<Result>(const T& encoded);

    2. Reused container version

    Resizes the provided binary_result container before writing to it.

    • void <codec>::decode(Result& binary_result, const char* encoded, size_t encoded_size);
    • void <codec>::decode(Result& binary_result, const T& encoded);

    3. Pre-allocated memory version

    Decodes into a raw buffer. This version will call abort() if the provided buffer is too small. It returns the actual number of bytes decoded.

    • size_t <codec>::decode([uint8_t|char]* binary_result, size_t binary_buffer_size, const char* encoded, size_t encoded_size);
    • size_t <codec>::decode([uint8_t|char]* binary_result, size_t binary_buffer_size, const T& encoded);
    // Example: Decoding to a vector
    std::vector<uint8_t> binary = cppcodec::base64::decode(encoded_string);
    
    // Example: Decoding into a pre-allocated buffer
    size_t max_possible = cppcodec::base64::decoded_max_size(encoded_string.size());
    std::vector<uint8_t> buffer(max_possible);
    size_t actual_decoded_size = cppcodec::base64::decode(buffer.data(), buffer.size(), encoded_string.data(), encoded_string.size());
  7. Reference the available codec variants

    master

    cppcodec provides several variants for Base64, Base32, and Hex encoding/decoding. Each variant is namespaced as a class (e.g., cppcodec::base64_url).

    Base64 Variants

    • base64_rfc4648: Standard alphabet (A-Z, a-z, 0-9, '+', '/'). Requires '=' padding. No line breaks allowed.
    • base64_url: Uses '-' and '_' instead of '+' and '/'. Safe for URLs/filenames. Requires '=' padding.
    • base64_url_unpadded: Same as base64_url but padding is optional. Encoding produces no padding.

    Base32 Variants

    • base32_rfc4648: RFC 4648 standard. Uses A-Z and 2-7. Requires '=' padding.
    • base32_crockford: Crockford's alphabet. Handles ambiguous characters (e.g., 'I'/'l' as '1') during decoding. No '=' padding used.
    • base32_hex: RFC 4648 extension using 0-9 and A-V. Requires '=' padding.

    Hex Variants

    • hex_upper: Outputs uppercase. Accepts lowercase. Requires even number of input symbols. Does not handle '0x' prefixes.
    • hex_lower: Outputs lowercase. Accepts uppercase. Requires even number of input symbols. Does not handle '0x' prefixes.