{"id":38134021,"url":"https://github.com/stephenfire/go-rtl","last_synced_at":"2026-01-16T22:40:04.080Z","repository":{"id":55831271,"uuid":"245653364","full_name":"stephenfire/go-rtl","owner":"stephenfire","description":"golang对象的序列化及反序列化 (encode and decode for golang object)","archived":false,"fork":false,"pushed_at":"2024-02-10T09:21:06.000Z","size":191,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-06-21T15:24:25.072Z","etag":null,"topics":["binary-protocol","decoder","encoder","go","version-compatible"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stephenfire.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,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2020-03-07T15:04:19.000Z","updated_at":"2023-11-27T01:04:16.000Z","dependencies_parsed_at":"2024-01-13T15:41:58.943Z","dependency_job_id":"a2ae9eb9-4e6f-4c54-84a4-c29b892b4fe9","html_url":"https://github.com/stephenfire/go-rtl","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/stephenfire/go-rtl","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephenfire%2Fgo-rtl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephenfire%2Fgo-rtl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephenfire%2Fgo-rtl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephenfire%2Fgo-rtl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stephenfire","download_url":"https://codeload.github.com/stephenfire/go-rtl/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stephenfire%2Fgo-rtl/sbom","scorecard":{"id":851538,"data":{"date":"2025-08-11","repo":{"name":"github.com/stephenfire/go-rtl","commit":"f5b78cc7f16b1f19e5769a12f054b33383703aa8"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.5,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/30 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":"Dangerous-Workflow","score":-1,"reason":"no workflows found","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":"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":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"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":"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":"SAST","score":0,"reason":"no SAST tool detected","details":["Warn: no pull requests merged into dev branch"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"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":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"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":"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":"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":"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:0","Info: FSF or OSI recognized license: Apache License 2.0: LICENSE: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":-1,"reason":"no releases found","details":null,"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":"Vulnerabilities","score":10,"reason":"0 existing vulnerabilities detected","details":null,"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-23T22:40:54.181Z","repository_id":55831271,"created_at":"2025-08-23T22:40:54.181Z","updated_at":"2025-08-23T22:40:54.181Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28485569,"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":["binary-protocol","decoder","encoder","go","version-compatible"],"created_at":"2026-01-16T22:40:03.762Z","updated_at":"2026-01-16T22:40:04.024Z","avatar_url":"https://github.com/stephenfire.png","language":"Go","readme":"# go-rtl\n\n这是一款使用简单，灵活方便，兼容性强的序列化工具。使用RTL(Recursive Typed and Length-prefixed)编码方式的golang对象的序列化及反序列化方法库。目前尚不支持其他语言。\n\n由于go基础库中不存在通用序列化工具；且如protobuf的第三方序列化需要预定义文件及相应的生成工具，当序列化类型经常变化或很多时，工作会显得有些繁琐。为了能够简单使用而开发这个通用序列化工具包。\n\n## 特性\n\n- 使用简单，可以将任意对象序列化成字节流，并反序列化为兼容的对象。\n- 序列化后，除原值外的附加信息很少。\n- struct类型升级可以兼容，即不同版本数据可以反序列化为不同版本类型的对象。\n- 支持类型的自定义序列化方式，可以与通用方法混用。\n\n## 使用限制\n\n- 因为使用反射，序列化会比硬编码的序列化方式慢。\n- 因为无法确定代码中希望为哪种类型对象，无法将数据反序列化至interface{}中。但序列化是可以的，因为此时的interface{}类型是明确的。\n- 在struct类型升级兼容性中，不支持删除其中的自定义序列化方式的字段。\n\n## 使用方法\n\n### 1. 引用\n\ngo.mod\n\n```\nrequire github.com/stephenfire/go-rtl v1.0.4\n```\n\ngo文件\n\n```go\nimport \"github.com/stephenfire/go-rtl\"\n```\n\n### 2. 序列化对象\n\n由于使用reflect包，所以struct只有public的属性才可以被序列化和反序列化。\n\n```go\n    type (\n        embeded struct {\n            A uint\n            B uint\n            C string\n            D []byte\n        }\n        basic struct {\n            A uint\n            B uint\n            C string\n            E int\n            F *big.Int\n            G embeded\n        }\n    )\n\n    obj := basic{\n        A: 22,\n        B: 33,\n        C: \"basic object\",\n        E: -983,\n        F: big.NewInt(9999999),\n        G: embeded{A: 44, B: 55, C: \"embeded object\", D: []byte(\"byte slice\")},\n    }\n```\n\n```go\n    buf := new(bytes.Buffer)\n    if err := Encode(obj, buf); err != nil {\n        t.Fatal(err)\n    }\n    bs := buf.Bytes()\n```\n\n或\n\n```go\n    bs, err := Marshal(obj)\n    if err != nil {\n        t.Fatal(err)\n    }\n```\n\n### 3. 反序列化对象，注意必须传入对象指针\n\n```go\n    decodedObj := new(basic)\n    if err := Decode(bytes.NewReader(bs), decodedObj); err != nil {\n        t.Fatal(err)\n    }\n```\n\n或\n\n```go\n    decodedObj := new(basic)\n    if err := Unmarshal(bs, decodedObj); err != nil {\n        t.Fatal(err)\n    }\n```\n\n### 4. 基础类型序列化\n\n基本上所有类型均可\n\n```go\n    var a, b int\n    a = 142857\n    if bs, err := Marshal(a); err == nil {\n        if err = Unmarshal(bs, \u0026b); err == nil {\n            if a == b {\n                t.Logf(\"%d == %d\", a, b)\n            } else {\n                t.Fatalf(\"%d \u003c\u003e %d\", a, b)\n            }\n        } else {\n            t.Fatal(err)\n        }\n    } else {\n        t.Fatal(err)\n    }\n\n    var x, y []int\n    x = []int{1, 4, 2, 8, 5, 7}\n    y = make([]int, 0)\n    if bs, err := Marshal(x); err == nil {\n        if err = Unmarshal(bs, \u0026y); err == nil {\n            if reflect.DeepEqual(x, y) {\n                t.Logf(\"%v == %v\", x, y)\n            } else {\n                t.Fatalf(\"%v \u003c\u003e %v\", x, y)\n            }\n        } else {\n            t.Fatal(err)\n        }\n    } else {\n        t.Fatal(err)\n    }\n```\n\n### 5. 类型兼容转化\n\n结构对象序列化的原数据与目标数据兼容时即可正常反序列化，与属性位置相关\n\n```go\n\ttype (\n\t\tsource struct {\n\t\t\tA []byte\n\t\t\tB []byte\n\t\t}\n\t\tdest struct {\n\t\t\tC string\n\t\t\tD []int\n\t\t}\n\t)\n\n\tsrc := \u0026source{A: []byte(\"a string\"), B: []byte{0x1, 0x2, 0x3, 0x4}}\n\tif bs, err := Marshal(src); err != nil {\n\t\tt.Fatal(err)\n\t} else {\n\t\tdst := new(dest)\n\t\tif err := Unmarshal(bs, dst); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tt.Logf(\"%+v -\u003e %+v\", src, dst)\n\t}\n```\n\n输出：\n\n```\n\u0026{A:[97 32 115 116 114 105 110 103] B:[1 2 3 4]} -\u003e \u0026{C:a string D:[1 2 3 4]}\n```\n\n\n\n### 6. 结构类型的版本兼容性\n\n通过使用标记 *rtlorder* 对结构属性进行排序。缺省为按定义顺序从0开始递增的值。\n\n序列化时，按rtlorder的顺序写入buffer，遇到不连续的情况时，用ZeroValue占位。\n\n反序列化时，按rtlorder的顺序读buffer，遇到不连续的情况时，跳过buffer中对应的位置；如果buffer数据不足，则反序列化对象中的后续属性均为缺省零值。\n\n```go\n\ttype (\n\t\tsource struct {\n\t\t\tA uint   // `rtlorder:\"0\"`\n\t\t\tB uint   // `rtlorder:\"1\"`\n\t\t\tC string // `rtlorder:\"2\"`\n\t\t\tD []byte // `rtlorder:\"3\"`\n\t\t}\n\t\tdest struct {\n\t\t\tE *big.Int `rtlorder:\"4\"`\n\t\t\tF int      `rtlorder:\"5\"`\n\t\t\tC string   `rtlorder:\"2\"`\n\t\t\tB uint     `rtlorder:\"1\"`\n\t\t}\n\t)\n\n\tsrc := \u0026source{\n\t\tA: 1,\n\t\tB: 2,\n\t\tC: \"Charlie\",\n\t\tD: []byte(\"not in\"),\n\t}\n\tif bs, err := Marshal(src); err != nil {\n\t\tt.Fatal(err)\n\t} else {\n\t\tdst := new(dest)\n\t\tif err := Unmarshal(bs, dst); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tt.Logf(\"%+v -\u003e %+v\", src, dst)\n\t}\n```\n\n输出：\n\n```\n\u0026{A:1 B:2 C:Charlie D:[110 111 116 32 105 110]} -\u003e \u0026{E:\u003cnil\u003e F:0 C:Charlie B:2}\n```\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstephenfire%2Fgo-rtl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstephenfire%2Fgo-rtl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstephenfire%2Fgo-rtl/lists"}