Skip to content

Latest commit

 

History

History
96 lines (76 loc) · 3.15 KB

README.md

File metadata and controls

96 lines (76 loc) · 3.15 KB

base64

A plain header-only RFC 4648 implementation, but with the most modern C++ API design.

All variants of RFC 4648 are supported and the Crockford variant is available.

Supports input from discontinuous multiple buffers.

Support non-padding for secure base64 url variant.

Support constexpr compile-time caculation.

C++23 required (consteval, concepts, endian and byteswap).

Status

encode done.

Synopsis

enum class rfc4648_kind
{
    base64,
    base64_url,
    base32,
    base32_lower,
    base32_hex,
    base32_hex_lower,
    base32_crockford,
    base32_crockford_lower,
    base16,
    base16_lower,
    hex = base16,
    hex_lower = base16_lower
};
// All special member functions are trivial and has non-trivial but noexcept default constructor
class rfc4648_ctx;
// All overloads are constexpr
template <rfc4648_kind Kind = rfc4648_kind::base64, bool Padding = true, typename In, typename Out>
Out rfc4648_encode(In begin, In end, Out first);
template <rfc4648_kind Kind = rfc4648_kind::base64, bool Padding = true, typename R, typename Out>
Out rfc4648_encode(R&& r, Out first);
template <rfc4648_kind Kind = rfc4648_kind::base64, typename In, typename Out>
Out rfc4648_encode(rfc4648_ctx& ctx, In begin, In end, Out first);
template <rfc4648_kind Kind = rfc4648_kind::base64, typename R, typename Out>
Out rfc4648_encode(rfc4648_ctx& ctx, R&& r, Out first);
template <rfc4648_kind Kind = rfc4648_kind::base64, bool Padding = true, typename Out>
Out rfc4648_encode(rfc4648_ctx& ctx, Out first);

R must satisfy ContinuousContainer , In must satisfy ContinuousIterator and Out must statisfy InputIterator and Output Iterator.

Let n is the length of the output as specified by RFC 4648.

If [begin, end) is not a valid range, or [first, first + n) is not a valid range, or if [begin, end) and [first, first + n) overlap, or if r and first overlap, the behavior is undefined.

Throws any exceptions from incrementing first. After an exception is thrown, [first, first + n) holds unspecified values, and ctx will be in an unspecified state.

Example

#include <string>
#include "rfc4648.hpp"
int main()
{
    std::string src{ "ABCDEFGHIJKLMN" };

    // single input buffer
    std::string dest;
    dest.resize((src.size() + 3) / 3 * 4);
    bizwen::rfc4648_encode(src.begin(), src.end(), dest.begin());

    // discontinuous multiple buffers
    std::string dest1;
    dest1.resize((src.size() * 3 + 3) / 3 * 4);
    // init context
    bizwen::rfc4648_ctx ctx;
    // init encode
    auto it = bizwen::rfc4648_encode(ctx, src.begin(), src.end(), dest1.begin());
    it = bizwen::rfc4648_encode(ctx, src.begin(), src.end(), it);
    it = bizwen::rfc4648_encode(ctx, src.begin(), src.end(), it);
    // final
    it = rfc4648_encode(ctx, it);

    // ranges
    std::string dest2;
    dest2.resize((src.size() + 3) / 3 * 4);
    bizwen::rfc4648_encode(src, dest2.begin());

    // byte array and wstring
    std::wstring dest3;
    dest3.resize((src.size() + 3) / 3 * 4);
    bizwen::rfc4648_encode((std::byte*)src.data(), (std::byte*)src.data() + src.size(), dest3.begin());
}