{"id":21836019,"url":"https://github.com/nocursor/base1","last_synced_at":"2025-03-21T14:33:58.731Z","repository":{"id":57479355,"uuid":"157285972","full_name":"nocursor/base1","owner":"nocursor","description":"Elixir library for encoding and decoding binaries in Base1 - Binary encoding inspired by unary numbers. For use with Multi-Base encoders.","archived":false,"fork":false,"pushed_at":"2018-11-12T22:45:44.000Z","size":10,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-27T14:27:35.997Z","etag":null,"topics":["base1","decoding","elixir","elixir-lang","elixir-library","encoding","multibase"],"latest_commit_sha":null,"homepage":null,"language":"Elixir","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/nocursor.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-11-12T22:27:05.000Z","updated_at":"2018-11-12T23:25:59.000Z","dependencies_parsed_at":"2022-09-17T05:02:12.446Z","dependency_job_id":null,"html_url":"https://github.com/nocursor/base1","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nocursor%2Fbase1","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nocursor%2Fbase1/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nocursor%2Fbase1/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nocursor%2Fbase1/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nocursor","download_url":"https://codeload.github.com/nocursor/base1/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244815395,"owners_count":20514943,"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":["base1","decoding","elixir","elixir-lang","elixir-library","encoding","multibase"],"created_at":"2024-11-27T20:32:03.845Z","updated_at":"2025-03-21T14:33:58.691Z","avatar_url":"https://github.com/nocursor.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Base1\n\nBase1 is an Elixir library for encoding and decoding Base1 binaries.\n\n`Base1` is an Elixir port of [Base1](https://github.com/qntm/base1). Please read the \"How it Works\" section to learn more.\n\n```\nBinary encoding inspired by unary numbers.\n```\n\nThe main reason `Base1` exists is to support Base1 encoding and decoding as part of [Multibase](https://github.com/multiformats/multibase) and other implementations that require dispatch to Base codecs.\n\n## Why\n\nYou probably should not use Base1 encoding unless you are building a multi-codec for Base encoding/decoding of some sort. It is grossly inefficient, slow, and according to some enlightened few, an abomination.\n\nIf these concerns still do not deter you, then you may find the following use-cases applicable for `Base1`:\n\n* Testing the durability of your laptop fans\n* Using CPU and memory that Chrome (or via Electron), poorly written software, or other programs fail to consume\n* Re-purposing your computer as a pancake griddle.\n* Implementing some sort of perverse unary computer emulator or behavior\n* \"A\" is an invaluable letter to you\n* You want to use a library that does not claim that it is fast. This is not fast unless your perception is wildly different than from a reasonable human.\n\n## Usage\n\nIf you want semi-unreasonable performance, it is best to work with lengths instead of binaries. You can do so as either integers or integers encoded as strings. The latter if for the case where your interface demands a binary (string) type returned.\n\nLet's first be unreasonable and encode a binary to see why lengths are better:\n\n```elixir\n# let's encode something very simple\nBase1.encode!(\u003c\u003c4\u003e\u003e)\n\"AAAAA\"\n\nBase1.encode!(\"1\")\n\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"\n\n# pay our respects\n Base1.encode!(\"F\")\n\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"\n\n# If we want to give our CPU a workout\nBase1.encode!(\"hello\")\n# output: lots of As, may take awhile\n\n# we need to be careful encoding things that will produce giant binaries, or otherwise encode length instead\nBase1.encode(\"huge binary to encode, but not really\")\n:error\n\nBase1.encode!(\"huge binary to encode, but not really\")\n# raises ** (ArgumentError) Data is too large to binary encode as Base1 52448966988976840295297313244602659742710332201806431846112755526506725455904981438524794 bytes are required. Use encode_length/1 and decode_length/1 instead.\n# perhaps we should listen....\n```\n\nLikewise, we can decode our binaries and show that encoding and decoding are transparent.\n\n```elixir\nBase1.decode!(\"AAAAA\")\n\u003c\u003c4\u003e\u003e\n\nBase1.decode!(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\")\n\"1\"\n\n#indeed\nBase1.decode(\"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\")\n\"F\"\n\n# Fully transparent\nBase1.encode!(\u003c\u003c1, 2, 3\u003e\u003e) |\u003e Base1.decode!()\n\u003c\u003c1, 2, 3\u003e\u003e\n\n# We can handle errors too if we want pattern matching\nBase1.encode!(\u003c\u003c1, 2, 3\u003e\u003e) |\u003e Base1.decode()\n{:ok, \u003c\u003c1, 2, 3\u003e\u003e}\n\n# bad input data\nBase1.decode(\"This is not base1, for it it does not scream to us\")\n:error\n```\n\nNow let's take a slightly more sane approach using lengths, all things considered.\n\n```elixir\n# encodes much faster than binary\nBase1.encode_length(\"hello\")                                                           \n452690013552\n\nBase1.decode_length!(452690013552)  \n\"hello\"\n\n# we can use our error handling flavor as before too\nBase1.decode_length(452690013552)  \n{:ok, \"hello\"}\n\n\n# also fully transparent and works better for larger input binaries than `encode/1`\n Base1.encode_length(\"Lettuceless Burritos Are Best Burritos\") |\u003e Base1.decode_length!()\n\"Lettuceless Burritos Are Best Burritos\"\n```\n\nFortunately, we can also take another approach if we really want our encoded data as binary, not numbers.\n\n```elixir\nBase1.encode_length_bin(\"hello\")\n\"452690013552\"\n\n# bigger strings now work too, just like with `encode_length/1`\nBase1.encode_length_bin(\"Big strings are better when they are string cheese\")\n\"680015850116389379759636622830644424760636765950574532108918486844800528727880164921633865142384902132161451816034661478\"\n\n# decoding works as everything else before it did\nBase1.decode_length_bin!(\"452690013552\")\n\"hello\"\n\n# and as before, we maintain transparency\nBase1.encode_length_bin(\"not as fun as encoding lots of As\") |\u003e Base1.decode_length_bin!() \n\"not as fun as encoding lots of As\"\n```\n\n## Limitations\n\n* `Base1.encode/1` - this function is not suitable for most data more than a few bytes long. The issue is that the Base1 design requires a very large block of memory allocated, while the limits outlined in the [Erlang Effieincy Guide](http://erlang.org/doc/efficiency_guide/advanced.html) conflict with this requirement. Attempting to `malloc` large amounts of bytes can crash the VM. As such, the current design prevents you from doing this. See \"Size of a binary\" for more discussion.\n    * If you feel inclined to come up with a design that fixes it, I welcome the input. As it stands right now, it's hardly worth addressing for my usage.\n* `Memory usage` - if your runtime memory allotment is very small, `encode/1` can still cause massive issues for you. Beware.\n* Common sense - use length encoding if for some reason you *really* need to encode something large\n\n## Installation\n\n`Base1` is available via [Hex](https://hex.pm/packages/base1). The package can be installed by adding `base1` to your list of dependencies in `mix.exs`:\n\n```elixir\ndef deps do\n  [\n    {:base1, \"~\u003e 0.1.0\"}\n  ]\nend\n```\n\nAPI Documentation can be found at [https://hexdocs.pm/base1/base1.html](https://hexdocs.pm/base1.html).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnocursor%2Fbase1","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnocursor%2Fbase1","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnocursor%2Fbase1/lists"}