{"id":31288880,"url":"https://github.com/hit9/bitproto","last_synced_at":"2025-09-24T13:03:05.389Z","repository":{"id":43380363,"uuid":"324063297","full_name":"hit9/bitproto","owner":"hit9","description":"The bit level data interchange format for serializing data structures (long term maintenance).","archived":false,"fork":false,"pushed_at":"2025-09-20T09:23:22.000Z","size":2149,"stargazers_count":151,"open_issues_count":6,"forks_count":19,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-09-20T11:28:35.873Z","etag":null,"topics":["bitproto","data-exchange","data-interchange","embedded","marshalling","protocol","serialization","serialization-library"],"latest_commit_sha":null,"homepage":"https://bitproto.readthedocs.io/","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hit9.png","metadata":{"files":{"readme":"README.md","changelog":"changes.rst","contributing":null,"funding":".github/FUNDING.yml","license":"license-bsd3.rst","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"custom":["https://www.paypal.me/chaowanghit9","https://writings.sh/about#%E8%B5%9E%E5%8A%A9%E6%88%91"]}},"created_at":"2020-12-24T04:16:54.000Z","updated_at":"2025-09-20T09:21:01.000Z","dependencies_parsed_at":"2024-01-07T03:52:02.867Z","dependency_job_id":"13a708dd-4074-45f6-8cb0-bd670521edfa","html_url":"https://github.com/hit9/bitproto","commit_stats":{"total_commits":548,"total_committers":2,"mean_commits":274.0,"dds":"0.018248175182481785","last_synced_commit":"b9025bfeefd37dab14ca98c238152f6179a24509"},"previous_names":[],"tags_count":14,"template":false,"template_full_name":null,"purl":"pkg:github/hit9/bitproto","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hit9%2Fbitproto","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hit9%2Fbitproto/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hit9%2Fbitproto/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hit9%2Fbitproto/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hit9","download_url":"https://codeload.github.com/hit9/bitproto/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hit9%2Fbitproto/sbom","scorecard":{"id":465566,"data":{"date":"2025-08-11","repo":{"name":"github.com/hit9/bitproto","commit":"c5c5ea17d410363da4349be545b404b68d5dd6b1"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.2,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/3 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/bench.yml:1","Warn: no topLevel permission defined: .github/workflows/ci.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/bench.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/hit9/bitproto/bench.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/bench.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/hit9/bitproto/bench.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/bench.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/hit9/bitproto/bench.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/bench.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/hit9/bitproto/bench.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/hit9/bitproto/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/hit9/bitproto/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:32: update your workflow using https://app.stepsecurity.io/secureworkflow/hit9/bitproto/ci.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/ci.yml:34: update your workflow using https://app.stepsecurity.io/secureworkflow/hit9/bitproto/ci.yml/master?enable=pin","Warn: pipCommand not pinned by hash: .github/workflows/bench.yml:40","Warn: pipCommand not pinned by hash: .github/workflows/bench.yml:44","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:40","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:44","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:48","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:49","Warn: pipCommand not pinned by hash: .github/workflows/ci.yml:54","Info:   0 out of   8 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   7 pipCommand dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: license-bsd3.rst:0","Info: FSF or OSI recognized license: BSD 3-Clause \"New\" or \"Revised\" License: license-bsd3.rst:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":0,"reason":"Project has not signed or included provenance with any releases.","details":["Warn: release artifact v1.1.1 not signed: https://api.github.com/repos/hit9/bitproto/releases/104137818","Warn: release artifact v1.1.0 not signed: https://api.github.com/repos/hit9/bitproto/releases/87701608","Warn: release artifact v1.0.1 not signed: https://api.github.com/repos/hit9/bitproto/releases/87308857","Warn: release artifact v1.1.1 does not have provenance: https://api.github.com/repos/hit9/bitproto/releases/104137818","Warn: release artifact v1.1.0 does not have provenance: https://api.github.com/repos/hit9/bitproto/releases/87701608","Warn: release artifact v1.0.1 does not have provenance: https://api.github.com/repos/hit9/bitproto/releases/87308857"],"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 30 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":7,"reason":"3 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: PYSEC-2024-48 / GHSA-fj7x-q9j7-g6q6","Warn: Project is vulnerable to: PYSEC-2023-292 / GHSA-9w2p-rh8c-v9g5","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-19T12:23:47.963Z","repository_id":43380363,"created_at":"2025-08-19T12:23:47.963Z","updated_at":"2025-08-19T12:23:47.963Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276754055,"owners_count":25698832,"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","status":"online","status_checked_at":"2025-09-24T02:00:09.776Z","response_time":97,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["bitproto","data-exchange","data-interchange","embedded","marshalling","protocol","serialization","serialization-library"],"created_at":"2025-09-24T13:01:49.633Z","updated_at":"2025-09-24T13:03:05.384Z","avatar_url":"https://github.com/hit9.png","language":"C","funding_links":["https://www.paypal.me/chaowanghit9","https://writings.sh/about#%E8%B5%9E%E5%8A%A9%E6%88%91"],"categories":["C","Packages, Libraries and RTOSes"],"sub_categories":["Serialization"],"readme":"# The bit level data interchange format\n\n[![](https://github.com/hit9/bitproto/workflows/bitproto%20ci/badge.svg)](https://github.com/hit9/bitproto/actions?query=workflow%3A%22bitproto+ci%22)\n[![](https://readthedocs.org/projects/bitproto/badge/?version=latest)](https://bitproto.readthedocs.io/en/latest/?badge=latest)\n[![](https://img.shields.io/badge/license-BSD3-brightgreen)](https://bitproto.readthedocs.io/en/latest/license.html)\n\n## Introduction\n\nBitproto is a fast, lightweight and easy-to-use bit level data\ninterchange format for serializing data structures.\n\nThe protocol describing syntax looks like the great\n[protocol buffers](https://developers.google.com/protocol-buffers),\nbut in bit level:\n\n```bitproto\nproto example\n\nmessage Data {\n    uint3 the = 1\n    uint3 bit = 2\n    uint5 level = 3\n    uint4 data = 4\n    uint11 interchange = 6\n    uint6 format = 7\n}  // 32 bits =\u003e 4B\n```\n\nThe `Data` above is called a message, it consists of 7 fields and will occupy a total\nof 4 bytes after encoding.\n\nThis image shows the layout of data fields in the encoded bytes buffer:\n\n![](docs/_static/images/data-encoding-sample.png)\n\n## Code Example\n\nCode example to encode bitproto message in C:\n\n```c\nstruct Data data = {.the = 7,\n                    .bit = 7,\n                    .level = 31,\n                    .data = 15,\n                    .interchange = 2047,\n                    .format = 63};\nunsigned char s[BYTES_LENGTH_DATA] = {0};\nEncodeData(\u0026data, s);\n// length of s is 4, and the hex format is\n// 0xFF 0xFF 0xFF 0xFF\n```\n\nAnd the decoding example:\n\n```c\nstruct Data d = {0};\nDecodeData(\u0026d, s);\n// values of d's fields is now:\n// 7 7 31 15 2047 63\n```\n\nSimple and green, isn't it?\n\nCode patterns of bitproto encoding are exactly similar in C, Go and Python.\n\n\n## Features\n\n- Supports bit level data serialization, **born for embedded development**.\n- Supports protocol [extensiblity](https://bitproto.readthedocs.io/en/latest/language.html#extensibility) , for forward-compatibility.\n- Easy to start, syntax is similar to the well-known protobuf.\n- Supports languages: [C](https://bitproto.readthedocs.io/en/latest/c-guide.html) (without dynamic memory allocation),\n  [Go](https://bitproto.readthedocs.io/en/latest/go-guide.html), [Python](https://bitproto.readthedocs.io/en/latest/python-guide.html).\n- Blazing fast encoding/decoding, [benchmark](https://bitproto.readthedocs.io/en/latest/performance.html).\n- We can **clearly know the size and arrangement** of encoded data, fields are compact without a single bit gap.\n\n## Schema Example\n\nAn example for a simple overview of the bitproto schema grammar:\n\n```bitproto\nproto pen\n\n// Constant value\nconst PEN_ARRAY_SIZE = 2 * 3;\n\n// Bit level enum.\nenum Color : uint3 {\n    COLOR_UNKNOWN = 0\n    COLOR_RED = 1\n    COLOR_BLUE = 2\n    COLOR_GREEN = 3\n}\n\n// Type alias\ntype Timestamp = int64\n\n// Composite structure\nmessage Pen {\n    Color color = 1\n    Timestamp produced_at = 2\n    uint3 number = 3\n    uint13 value = 4\n}\n\nmessage Box {\n    // Fixed-size array\n    Pen[PEN_ARRAY_SIZE] pens = 1;\n}\n```\n\nRun the bitproto compiler to generate C files:\n\n```bash\n$ bitproto c pen.bitproto\n```\n\nWhich generates two files: `pen_bp.h` and `pen_bp.c`.\n\nWe can have an overview of the generated code for the C language:\n\n```c\n// Constant value\n#define PEN_ARRAY_SIZE 6\n\n// Bit level enum.\ntypedef uint8_t Color; // 3bit\n\n#define COLOR_UNKNOWN 0\n#define COLOR_RED 1\n#define COLOR_BLUE 2\n#define COLOR_GREEN 3\n\n// Type alias\ntypedef int64_t Timestamp; // 64bit\n\n// Number of bytes to encode struct Pen\n#define BYTES_LENGTH_PEN 11\n\n// Composite structure\nstruct Pen {\n    Color color; // 3bit\n    Timestamp produced_at; // 64bit\n    uint8_t number; // 3bit\n    uint16_t value; // 13bit\n};\n\n// Number of bytes to encode struct Box\n#define BYTES_LENGTH_BOX 63\n\nstruct Box {\n    // Fixed-size array\n    struct Pen pens[6]; // 498bit\n};\n```\n\nYou can checkout directory [example](example) for a larger example.\n\n## Why bitproto ?\n\nThere is protobuf, why bitproto?\n\n### Origin\n\n\nThe bitproto was originally made when I'm working with embedded programs on\nmicro-controllers. Where usually exists many programming constraints:\n\n- tight communication size.\n- limited compiled code size.\n- better no dynamic memory allocation.\n\nProtobuf does not live on embedded field natively,\nit doesn't target ANSI C out of box.\n\n### Scenario\n\nIt's recommended to use bitproto over protobuf when:\n\n* Working on or with microcontrollers.\n* Wants bit-level message fields.\n* Wants to know clearly how many bytes the encoded data will occupy.\n\nFor scenarios other than the above, I recommend to use protobuf over bitproto.\n\n### Vs Protobuf\n\nThe differences between bitproto and protobuf are:\n\n* bitproto supports bit level data serialization, like the\n  [bit fields in C](https://en.wikipedia.org/wiki/Bit_field).\n\n* bitproto doesn't use any dynamic memory allocations. Few of\n  [protobuf C implementations](https://github.com/protocolbuffers/protobuf/blob/master/docs/third_party.md)\n  support this, except [nanopb](https://jpa.kapsi.fi/nanopb).\n\n* bitproto doesn't support varying sized data, all types are fixed sized.\n\n  bitproto won't encode typing or size reflection information into the buffer.\n  It only encodes the data itself, without any additional data, **the encoded data\n  is arranged like it's arranged in the memory**, with fixed size, without paddings,\n  think setting [aligned attribute to 1](https://stackoverflow.com/a/11772340)\n  on structs in C.\n\n* Protobuf works good on\n  [forward compatibility](https://developers.google.com/protocol-buffers/docs/overview#forward_compatibility).\n  For bitproto, this is the main shortcome of bitproto serialization until v0.4.0, since this version, it supports message's\n  [extensiblity](https://bitproto.readthedocs.io/en/latest/language.html#extensibility) by adding two bytes indicating\n  the message size at head of the message's encoded buffer.  This breaks the\n  traditional data layout design by encoding some minimal reflection\n  size information in, so this is designed as an optional feature.\n\n### Known Shortcomes\n\n* bitproto doesn't support varying sized types. For example, a `unit37` always occupies\n  37 bits even you assign it a small value like `1`.\n\n  Which means there will be lots of zero bytes if the meaningful data occupies little on\n  this type.  For instance, there will be `n-1` bytes left zero if only one byte of a\n  type with `n` bytes size is used.\n\n  Generally, we actually don't care much about this, since there are not so many bytes\n  in communication with embedded devices. The protocol itself is meant to be designed\n  tight and compact. Consider to wrap a compression mechanism like [zlib](https://zlib.net)\n  on the encoded buffer if you really care.\n\n* bitproto can't provide [best encoding performance](https://bitproto.readthedocs.io/en/latest/performance.html#the-optimization-mode)\n  with [extensibility](https://bitproto.readthedocs.io/en/latest/language.html#extensibility).\n\n  There's an [optimization mode](https://bitproto.readthedocs.io/en/latest/performance.html#the-optimization-mode) designed in bitproto\n  to generate plain encoding/decoding statements directly at code-generation time, since all\n  types in bitproto are fixed-sized, how-to-encode can be determined earlier at code-generation\n  time. This mode gives a huge performance improvement, but I still haven't found a way to\n  make it work with bitproto's extensibility mechanism together.\n\n## Documentation and Links\n\nDocumentation:\n\n- Website: [https://bitproto.readthedocs.io](https://bitproto.readthedocs.io)\n- Documentation in Chinese: [https://bitproto.readthedocs.io/zh/latest](https://bitproto.readthedocs.io/zh/latest)\n- [Quick start tutorial](https://bitproto.readthedocs.io/en/latest/quickstart.html)\n- [Grammar guide, in one page](https://bitproto.readthedocs.io/en/latest/language.html)\n\nEditor syntax highlighting plugins:\n\n- [Vim Plugin](editors/vim)\n- [PyCharm Settings](editors/pycharm)\n- [VS Code Extension](https://marketplace.visualstudio.com/items?itemName=hit9.bitproto)\n\nFaq:\n\n- [What’s the advantage of this over a bit field?](https://bitproto.readthedocs.io/en/latest/faq.html#what-s-the-advantage-of-this-over-a-bit-field)\n\nBlog posts:\n\n- Dev notes in Chinese: [https://writings.sh/post/bitproto-notes](https://writings.sh/post/bitproto-notes)\n\nLicense\n-------\n\n[BSD3](https://bitproto.readthedocs.io/en/latest/license.html)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhit9%2Fbitproto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhit9%2Fbitproto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhit9%2Fbitproto/lists"}