{"id":37785140,"url":"https://github.com/markdingo/netstring","last_synced_at":"2026-01-16T15:11:35.314Z","repository":{"id":166253920,"uuid":"641645268","full_name":"markdingo/netstring","owner":"markdingo","description":"Robust encoding and decoding of netstrings across network connections","archived":false,"fork":false,"pushed_at":"2025-08-11T01:38:44.000Z","size":87,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-08-11T03:20:33.072Z","etag":null,"topics":["go","golang","golang-package","netstring","serialization"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/markdingo.png","metadata":{"files":{"readme":"README.md","changelog":"ChangeLog.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2023-05-16T21:47:35.000Z","updated_at":"2025-08-11T01:38:48.000Z","dependencies_parsed_at":null,"dependency_job_id":"c79577f3-0602-40a1-9172-8ce37f61c1dd","html_url":"https://github.com/markdingo/netstring","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/markdingo/netstring","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markdingo%2Fnetstring","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markdingo%2Fnetstring/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markdingo%2Fnetstring/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markdingo%2Fnetstring/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/markdingo","download_url":"https://codeload.github.com/markdingo/netstring/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/markdingo%2Fnetstring/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28479406,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["go","golang","golang-package","netstring","serialization"],"created_at":"2026-01-16T15:11:35.204Z","updated_at":"2026-01-16T15:11:35.292Z","avatar_url":"https://github.com/markdingo.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003c!-- Always newline after period so diffs are easier to read. --\u003e\n# netstring - Robust encoding and decoding of netstrings\n\n## Introduction\n\nThe `netstring` package is a go implementation of\n[netstring](https://cr.yp.to/proto/netstrings.txt) serialization as originally specified\nby D. J. Bernstein [djb](https://cr.yp.to/cv.html).\n\n`netstring` provides an Encoder and a Decoder which are particularly suited to exchanging\nnetstrings across reliable transports such as TCP, WebSockets, D-Bus and the like.\n\nA netstring.Encoder writes go types as encoded netstrings to a supplied io.Writer. Encoder\nhas helper functions to encode basic go types such as bool, ints, floats, strings and\nbytes to netstrings. Structs, maps and other complex data structures are not supported.\nA netstring.Decoder accepts a byte-stream via its io.Reader and presents successfully\nparsed netstrings via the Decoder.Decode() and Decoder.DecodeKeyed() functions.\n\nAlternatively applications can use the message level Encoder.Marshal() and\nDecoder.Unmarshal() convenience functions to encode and decode a basic struct containing\n\"keyed\" netstrings with an end-of-message sentinel.\n\nThe overall goal of this package is to make it easy to attach netstring Encoders and\nDecoders to network connections or other reliable transports so that applications can\nexchange messages with either the lower level Encode*() and Decode*() functions or the\nhigher level Marshal() and Unmarshal() functions.\n\n### Project Status\n\n[![Build Status](https://github.com/markdingo/netstring/actions/workflows/go.yml/badge.svg)](https://github.com/markdingo/netstring/actions/workflows/go.yml)\n[![codecov](https://codecov.io/gh/markdingo/netstring/branch/main/graph/badge.svg)](https://codecov.io/gh/markdingo/netstring)\n[![CodeQL](https://github.com/markdingo/netstring/actions/workflows/codeql-analysis.yml/badge.svg)](https://github.com/markdingo/netstring/actions/workflows/codeql-analysis.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/markdingo/netstring)](https://goreportcard.com/report/github.com/markdingo/netstring)\n[![Go Reference](https://pkg.go.dev/badge/github.com/markdingo/netstring.svg)](https://pkg.go.dev/github.com/markdingo/netstring)\n\n## Background\n\nA netstring is a serialization technique where each value is expressed in the form\n[length] \":\" [value] \",\" where [value] is the payload, [length] is the length of [value]\nin decimal bytes and the colon and comma are leading and trailing delimiters respectively.\nAn example of the value \"The Hitchhiker's Guide to the Galaxy - D.A.\" encoded as a\nnetstring is:\n\n    \"42:The Hitchhiker's Guide to the Galaxy - DA.,\"\n\nStoring binary values in netstrings, while possible, is not recommended for obvious\nreasons of incompatible CPU architectures.\nBest practise is to convert all binary values to strings prior to encoding.\nTo assist in this best practice, helper functions are available to encode basic go-types\nsuch as ints and floats to netstrings.\nE.g. the function Encoder.EncodeInt() converts int(2^16) to the netstring:\n\n    \"5:65536,\"\n\n## \"Keyed\" netstrings\n\nIn addition to standard netstrings, this package supports \"keyed\" netstrings which are\nnothing more than netstrings where the first byte of [value] signifies a \"type\" which\ndescribes the rest of [value] in some useful way to the application.\n\nThe benefit of \"keyed\" netstrings is that they create a self-describing typing system\nwhich allows applications to encode multiple netstrings in a message without having to\nrely on positional order or nested netstrings to convey semantics or encapsulate a message.\n\nTo demonstrate the benefits of \"keyed\" netstrings, say you want to encode Name, Age,\nCountry and Height as netstrings to be transmitted to a remote service? With standard\nnetstrings you'd have to agree on the positional order for each value, say netstring #0\nfor Name, #1 for Age and so on.\n\nHere is what that series of netstrings looks like:\n\n    \"4:Name,3:Age,7:Country,6:Height,\"\n\nIf any of these values are optional, you'd still have to provide a zero length netstring\nto maintain positional order; however this creates the ambiguity as to whether the intent\nis to convey a zero length string or a NULL.\n\nWith \"keyed\" netstrings the values can be presented in any order and optional (or NULL)\nvalues are simply omitted.\nIn the above example if we assign the \"key\" of 'n' to Name, 'a' to Age, 'c' to Country and\n'h' to Height the series of \"keyed\" netstrings looks like:\n\n    \"5:nName,4:aAge,8:cCountry,7:hHeight,\"\n\nand if Age is optional the series of netstrings simply becomes:\n\n    \"8:cCountry,7:hHeight,5:nName,\"\n\nNote the change of order as well as the missing 'a' netstring?\nAll perfectly acceptable with \"keyed\" netstrings.\n\nTo gain the most benefit from \"keyed\" netstrings, the usual strategy is to reserve a\nspecific key value as an \"end-of-message\" sentinal which naturally is the last netstring\nin the message.\nThe convention is to use 'z' as the \"end-of-message\" sentinal as demonstrated in\nsubsequent examples.\n\n## Installation\n\nWhen imported by your program, `github.com/markdingo/netstring` should automatically\ninstall with `go mod tidy`.\n\nOnce installed, you can run the package tests with:\n\n```\n go test github.com/markdingo/netstring\n```\n\nas well as display the package documentation with:\n\n```\n go doc github.com/markdingo/netstring\n```\n\n## Usage and Examples\n\n``` go\nimport \"github.com/markdingo/netstring\"\n```\n\nTo create a message of netstrings, call NewEncoder() then call the various Encode*()\nfunctions to encode the basic go types.\nThis code fragment encodes a message into a bytes.Buffer.\n\n```\n var buf bytes.Buffer\n enc := netstring.NewEncoder(\u0026buf)\n enc.EncodeInt('a', 21)           // Age\n enc.EncodeString('C', \"Iceland\") // Country\n enc.EncodeString('n', \"Bjorn\")   // Name\n enc.EncodeBytes('z')             // End-of-message sentinel\n fmt.Println(buf.String())        // \"3:a21,8:CIceland,6:nBjorn,1:z,\"\n```\n\nAnd this fragment decodes the same message.\n\n```\n dec := netstring.NewDecoder(\u0026buf)\n k, v, e := dec.DecodeKeyed() // k=a, v=21\n k, v, e = dec.DecodeKeyed()  // k=C, v=Iceland\n k, v, e = dec.DecodeKeyed()  // k=n, v=Bjorn\n k, v, e = dec.DecodeKeyed()  // k=z End-Of-Message\n```\n\nThe message is more conveniently encoded with Marshal() as this fragment shows:\n\n```\n type record struct {\n      Age         int    `netstring:\"a\"`\n      Country     string `netstring:\"c\"`\n      Name        string `netstring:\"n\"`\n }\n\nvar buf bytes.Buffer\n enc := netstring.NewEncoder(\u0026buf)\n out := \u0026record{21, \"Iceland\", \"Bjorn\"}\n enc.Marshal('z', out)\n```\n\nand more conveniently decoded with Unmarshal() as this fragment shows:\n\n```\n dec := netstring.NewDecoder(\u0026buf)\n in := \u0026record{}\n dec.Unmarshal('z', in)\n```\n\nFull working programs can be found in the _examples directory.\n\n### Community\n\nIf you have any problems using `netstring` or suggestions on how it can do a better job,\ndon't hesitate to create an [issue](https://github.com/markdingo/netstring/issues) on the\nproject home page.\nThis package can only improve with your feedback.\n\n### Copyright and License\n\n`netstring` is Copyright :copyright: 2023 Mark Delany and is licensed under the BSD\n2-Clause \"Simplified\" License.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkdingo%2Fnetstring","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmarkdingo%2Fnetstring","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmarkdingo%2Fnetstring/lists"}