{"id":13734091,"url":"https://github.com/tplgy/cppcodec","last_synced_at":"2025-10-21T05:50:55.697Z","repository":{"id":47506034,"uuid":"48665943","full_name":"tplgy/cppcodec","owner":"tplgy","description":"Header-only C++11 library to encode/decode base64, base64url, base32, base32hex and hex (a.k.a. base16) as specified in RFC 4648, plus Crockford's base32. MIT licensed with consistent, flexible API.","archived":false,"fork":false,"pushed_at":"2022-09-06T18:42:09.000Z","size":182,"stargazers_count":605,"open_issues_count":16,"forks_count":109,"subscribers_count":25,"default_branch":"master","last_synced_at":"2024-08-04T03:03:20.528Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tplgy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-28T00:25:29.000Z","updated_at":"2024-07-31T22:56:58.000Z","dependencies_parsed_at":"2022-09-26T22:20:13.219Z","dependency_job_id":null,"html_url":"https://github.com/tplgy/cppcodec","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tplgy%2Fcppcodec","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tplgy%2Fcppcodec/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tplgy%2Fcppcodec/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tplgy%2Fcppcodec/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tplgy","download_url":"https://codeload.github.com/tplgy/cppcodec/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224720761,"owners_count":17358476,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-03T03:00:52.499Z","updated_at":"2025-10-21T05:50:50.641Z","avatar_url":"https://github.com/tplgy.png","language":"C++","readme":"# cppcodec\n\n[![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\u0026svg=true)](https://ci.appveyor.com/project/efidler/cppcodec)\n\nHeader-only C++11 library to encode/decode base64, base64url, base32, base32hex\nand hex (a.k.a. base16) as specified in RFC 4648, plus Crockford's base32.\n\nMIT licensed with consistent, flexible API. Supports raw pointers,\n`std::string` and (templated) character vectors without unnecessary allocations.\nCross-platform with measured decent performance and without compiler warnings.\n\n## Contents\n- ### [Usage](https://github.com/tplgy/cppcodec/blob/master/README.md#usage)\n- ### [Variants](https://github.com/tplgy/cppcodec/blob/master/README.md#variants)\n  - #### [base64](https://github.com/tplgy/cppcodec/blob/master/README.md#base64)\n  - #### [base32](https://github.com/tplgy/cppcodec/blob/master/README.md#base32)\n  - #### [hex](https://github.com/tplgy/cppcodec/blob/master/README.md#hex)\n- ### [Philosophy and trade-offs](https://github.com/tplgy/cppcodec/blob/master/README.md#philosophy-and-trade-offs)\n- ### [API](https://github.com/tplgy/cppcodec/blob/master/README.md#api)\n  - #### [Encoding](https://github.com/tplgy/cppcodec/blob/master/README.md#encoding)\n  - #### [Decoding](https://github.com/tplgy/cppcodec/blob/master/README.md#decoding)\n\n****\n\n# Usage\n\n1. Import cppcodec into your project (copy, git submodule, etc.)\n2. Add the cppcodec root directory to your build system's list of include directories\n3. Include headers and start using the API.\n\nSince cppcodec is a header-only library, no extra build step is needed.\nAlternatively, you can install the headers and build extra tools/tests with CMake.\n\n\n\n# Variants\n\nA number of codec variants exist for base64 and base32, defining different alphabets\nor specifying the use of padding and line breaks in different ways. cppcodec is designed\nto let you make a conscious choice about which one you're using, see below for a list of variants.\n\ncppcodec's approach is to implement encoding/decoding algorithms in different classes for namespacing (e.g. `cppcodec::base64_rfc4648`), with classes and their associated header files named verbatim after the codec variants.\n\nHere is an expected standard use of cppcodec:\n\n```C++\n#include \u003ccppcodec/base32_crockford.hpp\u003e\n#include \u003ccppcodec/base64_rfc4648.hpp\u003e\n#include \u003ciostream\u003e\n\nint main() {\n  using base32 = cppcodec::base32_crockford;\n  using base64 = cppcodec::base64_rfc4648;\n\n  std::vector\u003cuint8_t\u003e decoded = base64::decode(\"YW55IGNhcm5hbCBwbGVhc3VyZQ==\");\n  std::cout \u003c\u003c \"decoded size (\\\"any carnal pleasure\\\"): \" \u003c\u003c decoded.size() \u003c\u003c '\\n';\n  std::cout \u003c\u003c base32::encode(decoded) \u003c\u003c std::endl; // \"C5Q7J833C5S6WRBC41R6RSB1EDTQ4S8\"\n  return 0;\n}\n```\n\n(The prior example included \"baseXX_default_*.h\" includes, these are not recommended anymore and may eventually get deprecated.)\n\nCurrently supported codec variants are:\n\n### base64\n\n* `base64_rfc4648` uses the PEM/MIME/UTF-7 alphabet, that is (in order)\n  A-Z, a-z, 0-9 plus characters '+' and '/'. This is what's usually considered\n  the \"standard base64\" that you see everywhere and requires padding ('=') but\n  no line breaks. Whitespace and other out-of-alphabet symbols are regarded as\n  a parse error.\n* `base64_url` is the same as `base64_rfc4648` (and defined in the same RFC)\n  but uses '-' (minus) and '_' (underscore) as special characters instead of\n  '+' and '/'. This is safe to use for URLs and file names. Padding with '=' is\n  required, it will be generated when encoding to a string and regarded as a\n  parse error if it's not present when decoding.\n* `base64_url_unpadded` variant is the same as `base64_url`, but '=' padding\n  characters are optional. When encoding, no padding will be appended to the\n  resulting string. Decoding accepts either padded or unpadded strings.\n\n### base32\n\nAll base32 variants encode 5 bits as one (8-bit) character, which results in\nan encoded length of roughly 160% (= 8/5). Their selling point is mainly\ncase-insensitive decoding, no special characters and alphabets that can be\ncommunicated via phone.\n\n* `base32_rfc4648` implements the popular, standardized variant defined in\n  RFC 4648. It uses the full upper-case alphabet A-Z for the first 26 values\n  and the digit characters 2-7 for the last ten. Padding with '=' is required\n  and makes the encoded string a multiple of 8 characters. The codec accepts\n  no invalid symbols, so if you want to let the user enter base32 data then\n  consider replacing numbers '0', '1' and '8' with 'O', 'I' and 'B' on input.\n* `base32_crockford` implements [Crockford base32](http://www.crockford.com/wrmg/base32.html).\n  It's less widely used than the RFC 4648 alphabet, but offers a more carefully\n  picked alphabet and also defines decoding similar characters 'I', 'i', 'L'\n  'l' as '1' plus 'O' and 'o' as '0' so no care is required for user input.\n  Crockford base32 does not use '=' padding. Checksums are not implemented.\n  Note that the specification is ambiguous about whether to pad bit quintets to\n  the left or to the right, i.e. whether the codec is a place-based single number\n  encoding system or a concatenative iterative stream encoder. This codec variant\n  picks the streaming interpretation and thus zero-pads on the right. (See\n  http://merrigrove.blogspot.ca/2014/04/what-heck-is-base64-encoding-really.html\n  for a detailed discussion of the issue.)\n* `base32_hex` is the logical extension of the hexadecimal alphabet, and also\n  specified in RFC 4648. It uses the digit characters 0-9 for the first 10 values\n  and the upper-case letters A-V for the remaining ones. The alphabet is\n  conceptually simple, but contains all of the ambiguous number/letter pairs that\n  the other variants try to avoid. It is also less suitable for verbal\n  transmission. Padding with '=' is required and makes the encoded string a\n  multiple of 8 characters.\n\n### hex\n\n* `hex_upper` outputs upper-case letters and accepts lower-case as well.\n  This is an octet-streaming codec variant and for decoding, requires an even\n  number of input symbols. In other words, don't try to decode (0x)\"F\",\n  (0x)\"10F\" etc. with this variant, use a place-based single number codec\n  instead if you want to do this. Also, you are expected to prepend and remove\n  a \"0x\" prefix externally as it won't be generated when encoding / will be\n  rejected when decoding.\n* `hex_lower` outputs lower-case letters and accepts upper-case as well.\n  Similar to `hex_upper`, it's stream-based (no odd symbol lengths) and does\n  not deal with \"0x\" prefixes.\n\n\n\n# Philosophy and trade-offs\n\ncppcodec aims to support a range of codecs using a shared template-based implementation.\nThe focus is on a high-quality API that encourages correct use, includes error handling,\nand is easy to adopt into other codebases. As a header-only library, cppcodec can\nship implementations of several codecs and variants while only compiling the ones\nthat you actually use.\n\nGood performance is a goal, but not the topmost priority. In theory, templates allows\nto write generic code that is optimized for each specialization individually; however,\nin practice compilers still struggle to produce code that's as simple as a\nhand-written specialized function. On release builds, depending on the C++ compiler,\ncppcodec runs in between (approx.) 100% and 300% of time compared to \"regular\" optimized\nbase64 implementations. Both are beat by highly optimized implementations that use\nvector instructions (such as [this](https://github.com/aklomp/base64)) or buy better\nperformance with larger pre-computed tables (such as Chrome's base64 implementation).\nDebug builds of cppcodec are slower by an order of magnitude due to the use of templates\nand abstractions; make sure you use release or minimum-size builds in production.\n\n\n\n# API\n\nAll codecs expose the same API. In the below documentation, replace `\u003ccodec\u003e` with a\ndefault alias such as `base64`, `base32` or `hex`, or with the full namespace such as\n`cppcodec::base64_rfc4648` or `cppcodec::base32_crockford`.\n\nFor templated parameters `T` and `Result`, you can use e.g. `std::vector\u003cuint8_t\u003e`,\n`std::string` or anything that supports:\n* `.data()` and `.size()` for `T` (read-only) template parameters,\n* for `Result` template parameters, also `.reserve(size_t)`, `.resize(size_t)`\n  and `.push_back([uint8_t|char])`.\n\nIt's possible to support types lacking these functions, consult the code directly if you need this.\n\n\n### Encoding\n\n```C++\n// Convenient version, returns an std::string.\nstd::string \u003ccodec\u003e::encode(const [uint8_t|char]* binary, size_t binary_size);\nstd::string \u003ccodec\u003e::encode(const T\u0026 binary);\n\n// Convenient version with templated result type.\nResult \u003ccodec\u003e::encode\u003cResult\u003e(const [uint8_t|char]* binary, size_t binary_size);\nResult \u003ccodec\u003e::encode\u003cResult\u003e(const T\u0026 binary);\n\n// Reused result container version. Resizes encoded_result before writing to it.\nvoid \u003ccodec\u003e::encode(Result\u0026 encoded_result, const [uint8_t|char]* binary, size_t binary_size);\nvoid \u003ccodec\u003e::encode(Result\u0026 encoded_result, const T\u0026 binary);\n```\n\nEncode binary data into an encoded (base64/base32/hex) string.\nWon't throw by itself, but the result type might throw on `.resize()`.\n\n```C++\nsize_t \u003ccodec\u003e::encode(char* encoded_result, size_t encoded_buffer_size, const [uint8_t|char]* binary, size_t binary_size) noexcept;\nsize_t \u003ccodec\u003e::encode(char* encoded_result, size_t encoded_buffer_size, const T\u0026 binary) noexcept;\n```\n\nEncode binary data into pre-allocated memory with a buffer size of\n`\u003ccodec\u003e::encoded_size(binary_size)` or larger.\n\nReturns the byte size of the encoded string excluding null termination,\nwhich is equal to `\u003ccodec\u003e::encoded_size(binary_size)`.\n\nIf `encoded_buffer_size` is larger than required, a single null termination character (`'\\0'`)\nis written after the last encoded character. The `encoded_size()` function ensures that the required\nbuffer size is large enough to hold the padding required for the respective codec variant.\nProvide a buffer of size `encoded_size() + 1` to make it a null-terminated C string.\n\nCalls abort() if `encoded_buffer_size` is insufficient. (That way, the function can remain `noexcept`\nrather than throwing on an entirely avoidable error condition.)\n\n```C++\nsize_t \u003ccodec\u003e::encoded_size(size_t binary_size) noexcept;\n```\n\nCalculate the (exact) length of the encoded string based on binary size,\nexcluding null termination but including padding (if specified by the codec variant).\n\n\n### Decoding\n\n```C++\n// Convenient version, returns an std::vector\u003cuint8_t\u003e.\nstd::vector\u003cuint8_t\u003e \u003ccodec\u003e::decode(const char* encoded, size_t encoded_size);\nstd::vector\u003cuint8_t\u003e \u003ccodec\u003e::decode(const T\u0026 encoded);\n\n// Convenient version with templated result type.\nResult \u003ccodec\u003e::decode\u003cResult\u003e(const char* encoded, size_t encoded_size);\nResult \u003ccodec\u003e::decode\u003cResult\u003e(const T\u0026 encoded);\n\n// Reused result container version. Resizes binary_result before writing to it.\nvoid \u003ccodec\u003e::decode(Result\u0026 binary_result, const char* encoded, size_t encoded_size);\nvoid \u003ccodec\u003e::decode(Result\u0026 binary_result, const T\u0026 encoded);\n```\n\nDecode an encoded (base64/base32/hex) string into a binary buffer.\n\nThrows a cppcodec::parse_error exception (inheriting from std::domain_error)\nif the input data does not conform to the codec variant specification.\nAlso, the result type might throw on `.resize()`.\n\n```C++\nsize_t \u003ccodec\u003e::decode([uint8_t|char]* binary_result, size_t binary_buffer_size, const char* encoded, size_t encoded_size);\nsize_t \u003ccodec\u003e::decode([uint8_t|char]* binary_result, size_t binary_buffer_size, const T\u0026 encoded);\n```\n\nDecode an encoded string into pre-allocated memory with a buffer size of\n`\u003ccodec\u003e::decoded_max_size(encoded_size)` or larger.\n\nReturns the byte size of the decoded binary data, which is less or equal to\n`\u003ccodec\u003e::decoded_max_size(encoded_size)`.\n\nCalls abort() if `binary_buffer_size` is insufficient, for consistency with encode().\nThrows a cppcodec::parse_error exception (inheriting from std::domain_error)\nif the input data does not conform to the codec variant specification.\n\n```C++\nsize_t \u003ccodec\u003e::decoded_max_size(size_t encoded_size) noexcept;\n```\n\nCalculate the maximum size of the decoded binary buffer based on the encoded string length.\n\nIf the codec variant does not allow padding or whitespace / line breaks,\nthe maximum decoded size will be the exact decoded size.\n\nIf the codec variant allows padding or whitespace / line breaks, the actual decoded size\nmight be smaller. If you're using the pre-allocated memory result call, make sure to take\nits return value (the actual decoded size) into account.\n","funding_links":[],"categories":["Serialization","正则表达式","Cryptography and Security","C++"],"sub_categories":["序列化"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftplgy%2Fcppcodec","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftplgy%2Fcppcodec","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftplgy%2Fcppcodec/lists"}