{"id":13545101,"url":"https://github.com/qntm/base65536","last_synced_at":"2026-01-15T00:36:14.378Z","repository":{"id":2797706,"uuid":"47477730","full_name":"qntm/base65536","owner":"qntm","description":"Unicode's answer to Base64","archived":false,"fork":false,"pushed_at":"2026-01-01T14:49:15.000Z","size":2705,"stargazers_count":2181,"open_issues_count":0,"forks_count":57,"subscribers_count":25,"default_branch":"main","last_synced_at":"2026-01-04T21:59:01.250Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","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/qntm.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","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}},"created_at":"2015-12-06T00:13:55.000Z","updated_at":"2026-01-02T14:39:26.000Z","dependencies_parsed_at":"2024-01-10T13:05:42.342Z","dependency_job_id":"452aef48-69b1-46a2-bf84-3bb0cfd18a2d","html_url":"https://github.com/qntm/base65536","commit_stats":{"total_commits":142,"total_committers":10,"mean_commits":14.2,"dds":0.5633802816901409,"last_synced_commit":"5c3ef334ca82db439b9901421e2d1b44acd9364a"},"previous_names":["ferno/base65536"],"tags_count":19,"template":false,"template_full_name":null,"purl":"pkg:github/qntm/base65536","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qntm%2Fbase65536","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qntm%2Fbase65536/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qntm%2Fbase65536/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qntm%2Fbase65536/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/qntm","download_url":"https://codeload.github.com/qntm/base65536/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/qntm%2Fbase65536/sbom","scorecard":{"id":400028,"data":{"date":"2025-08-11","repo":{"name":"github.com/qntm/base65536","commit":"586b1310179d9bc7ab0cce9a25e8b98273934b26"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.7,"checks":[{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/workflow-1.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":"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":"Code-Review","score":0,"reason":"Found 0/7 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":"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":"Maintained","score":2,"reason":"3 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 2","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":"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/workflow-1.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/qntm/base65536/workflow-1.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/workflow-1.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/qntm/base65536/workflow-1.yml/main?enable=pin","Warn: npmCommand not pinned by hash: .github/workflows/workflow-1.yml:26","Info:   0 out of   2 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 npmCommand 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":"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.txt:0","Info: FSF or OSI recognized license: MIT License: LICENSE.txt: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":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 28 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: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw"],"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-18T19:53:01.864Z","repository_id":2797706,"created_at":"2025-08-18T19:53:01.865Z","updated_at":"2025-08-18T19:53:01.865Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28439810,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-15T00:34:46.850Z","status":"ssl_error","status_checked_at":"2026-01-15T00:34:46.551Z","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":[],"created_at":"2024-08-01T11:00:57.711Z","updated_at":"2026-01-15T00:36:14.333Z","avatar_url":"https://github.com/qntm.png","language":"JavaScript","readme":"# base65536\n\nBase65536 is a binary encoding optimised for UTF-32-encoded text. (For transmitting data through Twitter, Base65536 is now considered obsolete; see [Base2048](https://github.com/qntm/base2048).) This JavaScript module, `base65536`, is the first implementation of this encoding.\n\nBase65536 uses only [\"safe\" Unicode code points](https://qntm.org/safe) - no unassigned code points, no whitespace, no control characters, *etc.*.\n\nEfficiency ratings are averaged over long inputs. Higher is better.\n\n\u003ctable\u003e\n  \u003cthead\u003e\n    \u003ctr\u003e\n      \u003cth colspan=\"2\" rowspan=\"2\"\u003eEncoding\u003c/th\u003e\n      \u003cth colspan=\"3\"\u003eEfficiency\u003c/th\u003e\n      \u003cth rowspan=\"2\"\u003eBytes per Tweet *\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003cth\u003eUTF\u0026#x2011;8\u003c/th\u003e\n      \u003cth\u003eUTF\u0026#x2011;16\u003c/th\u003e\n      \u003cth\u003eUTF\u0026#x2011;32\u003c/th\u003e\n    \u003c/tr\u003e\n  \u003c/thead\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003ctd rowspan=\"5\"\u003eASCII\u0026#x2011;constrained\u003c/td\u003e\n      \u003ctd\u003eUnary / \u003ca href=\"https://github.com/qntm/base1\"\u003eBase1\u003c/a\u003e\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e0%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e0%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e0%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e1\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eBinary\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e13%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e6%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e3%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e35\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eHexadecimal\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e50%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e25%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e13%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e140\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eBase64\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e\u003cstrong\u003e75%\u003c/strong\u003e\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e38%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e19%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e210\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eBase85 †\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e80%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e40%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e20%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e224\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd rowspan=\"4\"\u003eBMP\u0026#x2011;constrained\u003c/td\u003e\n      \u003ctd\u003e\u003ca href=\"https://github.com/qntm/hexagram-encode\"\u003eHexagramEncode\u003c/a\u003e\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e25%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e38%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e19%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e105\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ca href=\"https://github.com/qntm/braille-encode\"\u003eBrailleEncode\u003c/a\u003e\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e33%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e50%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e25%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e140\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ca href=\"https://github.com/qntm/base2048\"\u003eBase2048\u003c/a\u003e\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e56%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e69%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e34%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e\u003cstrong\u003e385\u003c/strong\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ca href=\"https://github.com/qntm/base32768\"\u003eBase32768\u003c/a\u003e\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e63%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e\u003cstrong\u003e94%\u003c/strong\u003e\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e47%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e263\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd rowspan=\"3\"\u003eFull Unicode\u003c/td\u003e\n      \u003ctd\u003e\u003ca href=\"https://github.com/keith-turner/ecoji\"\u003eEcoji\u003c/a\u003e\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e31%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e31%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e31%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e175\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ca href=\"https://github.com/qntm/base65536\"\u003eBase65536\u003c/a\u003e\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e56%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e64%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e\u003cstrong\u003e50%\u003c/strong\u003e\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e280\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\u003ca href=\"https://github.com/qntm/base131072\"\u003eBase131072\u003c/a\u003e ‡\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e53%+\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e53%+\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e53%\u003c/td\u003e\n      \u003ctd style=\"text-align: right;\"\u003e297\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n\\* Up to 280 Unicode characters give or take Twitter's complex \"weighting\" calculation.\u003cbr/\u003e\n† Base85 is listed for completeness but all variants use characters which are considered hazardous for general use in text: escape characters, brackets, punctuation *etc.*.\u003cbr/\u003e\n‡ Base131072 is a work in progress, not yet ready for general use.\u003cbr/\u003e\n\n## Installation\n\n```bash\n$ npm install base65536\n```\n\n## Usage\n\n```js\nimport { encode, decode } from 'base65536'\n\nconst uint8Array = new Uint8Array([104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100])\n\nconst string = encode(uint8Array)\nconsole.log(string);\n// 6 code points, '驨ꍬ啯𒁷ꍲᕤ'\n\nconst uint8Array2 = new Uint8Array( decode(string))\nconsole.log(uint8Array2);\n// [104, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]\n```\n\n## API\n\n`base65536` accepts and returns `Uint8Array`s. Note that every Node.js `Buffer` is a `Uint8Array`. A `Uint8Array` can be converted to a Node.js `Buffer` like so:\n\n```js\nconst buffer = Buffer.from(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength)\n```\n\n### encode(uint8Array)\n\nEncodes a [`Uint8Array`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array) and returns a Base65536 `String`, suitable for passing safely through almost any \"Unicode-clean\" text-handling API. This string contains no special characters and is immune to Unicode normalization. The string encodes two bytes per code point.\n\n### decode(string)\n\nDecodes a Base65536 `String` and returns a `Uint8Array` containing the original binary data.\n\n## Background\n\n### Why?\n\nErm.\n\nI wanted people to be able to share [HATETRIS](http://qntm.org/files/hatetris/hatetris.html) replays via Twitter.\n\nHATETRIS has four buttons: left, right, down and rotate. A single move in HATETRIS therefore encodes two bits of information. Although a game of HATETRIS may extend for an arbitrary number of keystrokes (simply press rotate forever), in general, the longer the game goes on, the higher one's score. In late 2015, when Base65536 was first developed, the world record HATETRIS replay (30 points) was 1,440 keystrokes = 2,880 bits long, and HATETRIS replays were encoded as hexadecimal, with each hexadecimal digit encoding 4 bits = 2 keystrokes, and spaces added for clarity/legibility, then presented as text, like so:\n\n\u003e C02A AAAA AAAB 00AA AAAA AC08 AAAA AAC2 AAAA AAAA C2AA AAAA AEAA AAAA AA56\n\u003e AAAA AAAA B55A AAAA AA96 AAAA AAAA D5AA AAAA A9AA AAAA AAB5 AAAA AAAA AAAA\n\u003e AAAA DAAA AAAA 9756 AAAA AA8A AAAA AAAB AAAA AAAB 5AAA AAAB 56AA AAAA AAAA\n\u003e A82A AAAA B00A AAAA A6D6 AB55 6AAA AAA9 4AAA AAA6 AAAA AD56 AAAA B56A AAAA\n\u003e 032A AAAA A65B F00A AAAA AA6E EFC0 2AAA AAAA EB00 AAAA AAA8 0AAA AAAA 802A\n\u003e AAAA AA54 AAAA AAA1 AAAA AAA0 AAAA AAA0 0AAA AAAA C02A AAAA B002 AAAA B00A\n\u003e AAAC 2AAA AAB0 AAAA AEAA AAA9 5AAA AAA9 D5AA AAA5 AAAA AAB5 6AAA A6AA AAAB\n\u003e 5AAA AAAA AAAA DAAA AAD5 56AA AA2A AAAA BAAA AAD6 AAAB 56AA AAAA 82AA AC02\n\u003e AAA7 B5AA D556 AAAA 52AA A6AA B55A AB56 AA80 FCAA AAA5 583F 0AAA A9BB BF00\n\u003e AAAA AE80 32AA AA82 FAAA A802 AAAA 96AA AA1A AAA8 2AAA A00A AAAB 00AA AB00\n\u003e AAB0 AAAB 0AAB AAA9 5AAA AD56 AA5A AAB5 6AAC 02A9 AAAB 5AAA AAAD AAB5 5AA2\n\u003e AAAE AA0A AAB2 AAD5 6AB5 AA02 AAA0 0AAA B55A AD6A BAAC 2AAB 0AA0 C2AA C02A\n\nThat's 899 characters including spaces, or 720 characters if the spaces were removed. Were the hexadecimal characters converted to binary, one would have 360 bytes, and were the binary expressed in Base64, one would have 480 characters. This made replays impractical to share via Twitter, which at the time supported Tweets of only at most 140 characters.\n\nUsing elementary run-length encoding, using two bits of keystroke and two bits of run length, the replay shrinks to 2040 bits *i.e.* 255 bytes *i.e.* 340 characters of Base64. But that's still much too large.\n\nHowever, interestingly, \"[Tweet length is measured by the number of codepoints in the NFC normalized version of the text.](https://dev.twitter.com/overview/api/counting-characters)\", *not* by counting the number of bytes in any specific encoding of the text. Realising this, I developed Base65536. Whereas Base64 encodes only 6 bits per Unicode code point for a potential maximum of 105 bytes per Tweet, Base65536 encodes 16 bits per Unicode code point for a vastly improved **280 bytes per Tweet**.\n\nExpressing the 255-byte run-length encoded replay as Base65536, we get a string which is a svelte 128 code points long:\n\n\u003e 𤇃𢊻𤄻嶜𤄋𤇁𡊻𤄛𤆬𠲻𤆻𠆜𢮻𤆻ꊌ𢪻𤆻邌𤆻𤊻𤅋𤲥𣾻𤄋𥆸𣊻𤅛ꊌ𤆻𤆱炼綻𤋅𤅴薹𣪻𣊻𣽻𤇆𤚢𣺻赈𤇣綹𤻈𤇣𤾺𤇃悺𢦻𤂻𤅠㢹𣾻𤄛𤆓𤦹𤊻𤄰炜傼𤞻𢊻𣲻𣺻ꉌ邹𡊻𣹫𤅋𤇅𣾻𤇄𓎜𠚻𤊻𢊻𤉛𤅫𤂑𤃃𡉌𤵛𣹛𤁐𢉋𡉻𡡫𤇠𠞗𤇡𡊄𡒌𣼻燉𣼋𦄘炸邹㢸𠞻𠦻𡊻𣈻𡈻𣈛𡈛ꊺ𠆼𤂅𣻆𣫃𤮺𤊻𡉋㽻𣺬𣈛𡈋𤭻𤂲𣈻𤭻𤊼𢈛儛𡈛ᔺ\n\nThis [fit comfortably in a Tweet](https://twitter.com/qntm/status/673523018224791552), with an extravagant 12 characters left over for commentary. Of course, worse HATETRIS players typically end up with shorter replays, leaving more room for invective.\n\n## Later developments\n\nThe 30-point record above was set on 4 May 2010. On 6 June 2017 the record was broken with a 31-point run whose Base65536 replay:\n\n\u003e 𤂻愈䲻㰋𣻋㼘𤇀𠞻𤇋傜𣾻𤇋𤆦𠪵𤃄遈肼𡮻𤆻絈𤇄𤆴𥆹𤅛𤆻𤺸𤅋𤄋𥆺𠞻𤆻𥆐𠪻𠪄𤇄𣺁𤄋𡪄郈𢪻𤇄㲸㰈𤄋𤊁𤂻𤄜𡪼𣢻𡊀𣺻丘𤇋𤩘𣾻𥄈𠪻𤃋㰈𤀛蹌𤅋𤄋𡚡𤇋𤀜緊𣥋𤆜𤆁𠲼綹𥅘𣹋䰉𣼋蹊𤽋𤅋𤆌𤆰𡚡䲻𤇂𤆤𡪥𣚻𣢻𠮤𤺸𤅋𤂄𡘜羹𤇆㾸㶹𤀌𢙛𡞐𤆌㶺𥄩𡮴㺻𣣋𤃋𣛋𥆀𤺦ꉊ𣛄𠚀𠚜𤆀职𢊻徻蹈𢫄𣾻𤄌𤛋𡛁𡫋羌𡏋㼈𢢌𢢬𥂐𡫅𣪄𡊤肻𣊐㼸𢪠𢪄䂸𡪄趜𥀩𡙋𢢀𡊀𣺆㼩𤂄𡫇𡪴䲹𥄉𨂀\n\nwas 154 code points long, too long to fit in a Tweet.\n\nLater in 2017, Twitter \u003ca href=\"https://blog.twitter.com/official/en_us/topics/product/2017/Giving-you-more-characters-to-express-yourself.html\"\u003eincreased the maximum Tweet length\u003c/a\u003e from 140 to 280 Unicode code points... except that code points U+1100 HANGUL CHOSEONG KIYEOK upwards now counted double. This effectively divided Unicode into \"light\" code points and \"heavy\" code points. Since Base65536 exclusively uses heavy code points, a new \"long\" Tweet could still only contain at most 140 code points of Base65536, or 280 bytes.\n\nThese two events spurred me to develop a new binary encoding optimised for the new long Tweets, [Base2048](https://github.com/qntm/base2048). Using Base2048, up to 385 bytes can fit in a Tweet. The previously unTweetable record 31-point replay becomes:\n\n\u003e ௨ഖƌݯߜࠏІWƑsໃa௨೯ܘݷಳජଈیԪؼʥݺԥඞܘݲࠐڄໂঅமةໃݹ௧ړІٽ௨൞ໃZ௨ಘІܥࠐΣІZߜටȜখذජНݹߛeʛݹߤปເѧ௩ԚໂՉࢸටuа௨સȣݷłقෆঅਏeܘԔצقషݸɢڠຜঀಧҸມѧஐට༪൩ԊಅഫܡथsถԡԦԚໃɥஸقࡈɕɠɈไݸצقషݰਵϺФঅஓػݐɓԞуຯɕझࡈ๐ݞझࢶІݞमปദஈƉؿଭݪஸҩЂ൸ԛمϦGƁҨVھԥචЅշࡂ෮लݷƘණ໘ࠅƘಧНקࢻҨฆӘದԋϝପࠑ੧ͳݲடփරݞਵΚϼɢԒԺٳѦԤࠌξGಘسਯܥஶҋϮτथlϼʔ\n\nwhich, yes, [fits just fine](https://twitter.com/qntm/status/931634672236449793).\n\nBase2048 sadly renders Base65536 obsolete for its original intended purpose of sending binary data through Twitter. Base2048 is now used instead of Base65536 for rendering HATETRIS replays.\n\nHowever, Base65536 remains the state of the art for sending binary data through text-based systems which naively count Unicode code points, particularly those using the fixed-width UTF-32 encoding.\n\n## Unicode has 1,114,112 code points, most of which we aren't using. Can we go further?\n\nNot yet.\n\nTo encode one additional bit per code point, we need to *double* the number of code points we use from 65,536 to 131,072. This would be a new encoding, [Base131072](https://github.com/qntm/base131072), and its UTF-32 encoding efficiency would be 53% vs. 50% for Base65536. (Note that in UTF-16, [Base32768](https://github.com/qntm/base32768) significantly outperforms either choice, and in UTF-8, Base64 remains the preferred choice.)\n\nHowever, as of Unicode 10.0, [`safe-code-point`](https://github.com/qntm/safe-code-point) returns only 116,813 safe code points altogether. Perhaps future versions of Unicode will eventually assign more characters and make this possible, but even when this eventually happens, it seems unlikely that the characters will be arranged neatly in the blocks of 256 which make Base65536 so small and simple. It might not be worth the trouble...\n\n## License\n\nMIT\n\n## Other versions\n\n* [`base65536-stream`](https://github.com/qntm/base65536-stream) - streaming implementation\n* [`base65536-cli`](https://github.com/qntm/base65536-cli) - command-line tool\n* [`base65536-online`](https://github.com/lixiang810/base65536-online) - use base65536 to encode / decode text online\n\n## In other languages\n\nThis is a JavaScript implementation of the Base65536 encoding. There are other implementations:\n\n* [Python](https://github.com/Parkayun/base65536)\n* [Go](https://github.com/Nightbug/go-base65536)\n* [Ruby](https://github.com/Nightbug/base65536-ruby)\n* [PHP](https://github.com/hevertonfreitas/base65536)\n* [C](https://git.gir.st/base65536.git)\n* [Rust](https://github.com/nuew/base65536)\n* [C#](https://github.com/cyberdot/base65536)\n\nPlanning an implementation of your own? You may find [these test case files](https://github.com/qntm/base65536-test)  useful.\n","funding_links":[],"categories":["JavaScript","Cryptography"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqntm%2Fbase65536","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fqntm%2Fbase65536","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fqntm%2Fbase65536/lists"}