{"_id":"d64","_rev":"4106731","name":"d64","description":"dominictarr style base64, like base64 but lexiographically sortable","dist-tags":{"latest":"1.0.0"},"maintainers":[{"name":"nopersonsmodules","email":"nopersonsmodules@gmail.com"}],"time":{"modified":"2026-01-11T18:56:15.000Z","created":"2014-01-27T21:51:10.251Z","1.0.0":"2014-01-27T21:55:40.774Z","0.0.0":"2014-01-27T21:51:10.251Z"},"users":{},"author":{"name":"Dominic Tarr","email":"dominic.tarr@gmail.com","url":"dominictarr.com"},"repository":{"type":"git","url":"git://github.com/dominictarr/d64.git"},"versions":{"1.0.0":{"name":"d64","description":"dominictarr style base64, like base64 but lexiographically sortable","version":"1.0.0","homepage":"https://github.com/dominictarr/d64","repository":{"type":"git","url":"git://github.com/dominictarr/d64.git"},"scripts":{"test":"set -e; for t in test/*.js; do node $t; done"},"author":{"name":"Dominic Tarr","email":"dominic.tarr@gmail.com","url":"dominictarr.com"},"license":"MIT","bugs":{"url":"https://github.com/dominictarr/d64/issues"},"_id":"d64@1.0.0","dist":{"shasum":"4002a87e850cbfc9f9d9706b60fca613a3336e90","size":5089,"noattachment":false,"key":"/d64/-/d64-1.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/d64/download/d64-1.0.0.tgz"},"_from":".","_npmVersion":"1.3.21","_npmUser":{"name":"dominictarr","email":"dominic.tarr@gmail.com"},"maintainers":[{"name":"nopersonsmodules","email":"nopersonsmodules@gmail.com"}],"directories":{},"publish_time":1390859740774,"_hasShrinkwrap":false,"_cnpm_publish_time":1390859740774,"_cnpmcore_publish_time":"2021-12-16T16:40:51.840Z"},"0.0.0":{"name":"d64","description":"dominictarr style base64, like base64 but lexiographically sortable","version":"0.0.0","homepage":"https://github.com/dominictarr/d64","repository":{"type":"git","url":"git://github.com/dominictarr/d64.git"},"scripts":{"test":"set -e; for t in test/*.js; do node $t; done"},"author":{"name":"Dominic Tarr","email":"dominic.tarr@gmail.com","url":"dominictarr.com"},"license":"MIT","bugs":{"url":"https://github.com/dominictarr/d64/issues"},"_id":"d64@0.0.0","dist":{"shasum":"e56d34788bf0e328669f23b16f8f821473db3d8e","size":4019,"noattachment":false,"key":"/d64/-/d64-0.0.0.tgz","tarball":"http://registry.cnpm.dingdandao.com/d64/download/d64-0.0.0.tgz"},"_from":".","_npmVersion":"1.3.21","_npmUser":{"name":"dominictarr","email":"dominic.tarr@gmail.com"},"maintainers":[{"name":"nopersonsmodules","email":"nopersonsmodules@gmail.com"}],"directories":{},"publish_time":1390859470251,"_hasShrinkwrap":false,"_cnpm_publish_time":1390859470251,"_cnpmcore_publish_time":"2021-12-16T16:40:52.071Z"}},"readme":"# d64\n\na copy-pastable, url friendly, ascii embeddable, lexiographicly sortable binary encoding.\n\n## Example\n\n``` js\nvar d64  = require('d64')\n\nvar buf  = new Buffer([0x01, 0x23, 0x45, 0x67, 0x89, 0xab])\nvar str  = d64.encode(binary)\nvar buf2 = d64.decode(string)\n```\n\n## Encoding binary as base 64 ascii\n\nThere is already a well described base64 encoding [[1]]\nbut it has some downsides, base 64 encoded are not lexiographically sortable,\nbecause the ascii characters do not have the same ordering as they unencoded\nbytes they encode. Consistent ordering is very useful when building database\nwhich needs sorting in an enviroment where a binary key is not possible\n(for example, in indexeddb or levelup[[2]] in the browser)\n\nAlso, it's simplest if all the characters used do not need to be encoded in\ncommon text inputs, such as URLs, or the shell. Finally, some of the \nnon-alphanumeric characters may  trigger line breaks in a textarea,\nwhich can make the encoded string ambigious.\n\nThere are other encodings which have addressed some of these issues,\nsuch as hex and base32[[1]], base58[[3]].\nbase16 or base32 expand the message more than necessary,\nand since base58 does not line up with a whole number of bits,\nthen the implementation is not simple, and requires big integers.\n\nThere are also other interesting encodings such as zbase32 [[4]] or proquints [[5]]\nwhich are optimized for human transmission (recognition and pronouncability).\n\nd64 is optimized for being easy to implement, fast to encode/decode,\nand that a collection of encoded strings should have the same bytewise ordering\nas they would unencoded.\n\nthe 64 characters, in ascending order, are `.` (full stop) `0-9` (the digits),\n`A-Z` (the capital letters), `_` (underscore), `a-z` (the lowercase letters).\n\n``` js\nvar chars = '.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'\n```\n\n## Justification for choice of characters\n\nThere are only 62 alphanumeric characters, so we need to pick two more.\nfirst, lets find the characters which can be used in URLs without escaping them.\n\n``` js\nvar sensible = '!@#$%^&*(){}?+|_\"<>\\',-.'\n  .split('').sort().map(encodeURIComponent)\n  .filter(function (e) { return e.length ==1 })\n  .join('')\n```\n\nthe non-encoded characters are `!'()*-._~`\n\n`_` is an obvious choice, because it's very nearly always a valid character\nwithin a variable name, so it's treated like a aphabetic character in most cases.\n\nIt's better not to choose `!` and `~`, because they are the first and last printable\ncharacters, so they are quite useful for delimiting strings while maintaining the sorting\nproperties - for instance strings of d64.\n\n`!` and `~` are commonly used in levelup[[2]], and that is one of the target applications for d64.\n\n`-` causes text areas to line wrap, so that is out.\n\n`'*()` are all significant in bash.\n\nthat leaves just `.`\nIt feels weird to use `.` as a value, but all the other choices have been eliminated.\n\n## Invalid encoded lengths\n\nd64 does not use any padding at the end, as in base64.\n(there are no suitable characters left, anyway) the string length mod 4\na d64 string encodes is always 2, 3, or 0. If the length % 4 is 1,\nthat means there is 6 bits overhanging which is invalid.\n\nFor characters which overhang the byte array, (i.e. the last character if length % 4 == 2 or 3)\nthe overhanging portion must encode 0 bits.\n\n`if length % 4 == 2` then 4 bits overhang, the valid characters are: `.FVK`\n`if length % 4 == 3` then 2 bits overhang, the valid characters are: `.37BFJNRVZcgkosw`\n\n``` js\nvar overhang2bits = chars.split('').filter(function (_, i) { return !(i&0xf) }).join('')\n// ==> .FVK\nvar overhang4bits = chars.split('').filter(function (_, i) { return !(i&0x3) }).join('')\n// ==> .37BFJNRVZcgkosw\n```\n\nAlthough everything is for a reason and carefully described, that doesn't mean inventing\nyour own encoding isn't a douchebag thing to do, but hey - everyone else does it!\n\n## References\n\n1. <http://www.rfc-base.org/txt/rfc-3548.txt>\n2. <https://github.com/rvagg/node-levelup>\n3. <http://search.cpan.org/~miyagawa/Encode-Base58-0.01/lib/Encode/Base58.pm>\n4. <http://search.cpan.org/~gwyn/Convert-zBase32-0.0201/lib/Convert/zBase32.pm>\n5. <http://arxiv.org/html/0901.4016>\n\n## License\n\nMIT\n\n***\n\n[1]: http://www.rfc-base.org/txt/rfc-3548.txt\n[2]: https://github.com/rvagg/node-levelup\n[3]: http://search.cpan.org/~miyagawa/Encode-Base58-0.01/lib/Encode/Base58.pm\n[4]: http://search.cpan.org/~gwyn/Convert-zBase32-0.0201/lib/Convert/zBase32.pm\n[5]: http://arxiv.org/html/0901.4016\n\n","_attachments":{},"homepage":"https://github.com/dominictarr/d64","bugs":{"url":"https://github.com/dominictarr/d64/issues"},"license":"MIT"}