https://github.com/olsonpm/couchdb-base64
https://github.com/olsonpm/couchdb-base64
Last synced: about 1 year ago
JSON representation
- Host: GitHub
- URL: https://github.com/olsonpm/couchdb-base64
- Owner: olsonpm
- License: other
- Created: 2018-04-05T16:13:11.000Z (about 8 years ago)
- Default Branch: dev
- Last Pushed: 2018-08-03T21:39:18.000Z (almost 8 years ago)
- Last Synced: 2025-01-20T23:46:19.133Z (over 1 year ago)
- Language: JavaScript
- Size: 14.6 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
- License: license.txt
Awesome Lists containing this project
README
## Base64 intended for use with couchdb
- [What is this?](#what-is-this)
- [Why create it](#why-create-it)
- [Install](#install)
- [Character set used](#character-set-used)
- [Simple example](#simple-example)
- [API](#api)
- [Test](#test)
### What is this?
An encoding scheme intended for use with couchdb's document ids. It is a naive
solution to the problem noted [in their documentation](http://docs.couchdb.org/en/2.1.1/maintenance/performance.html#document-s-id).
> Consequently you should consider generating ids yourself, allocating them
> sequentially and using an encoding scheme that consumes fewer bytes. For
> example, something that takes 16 hex digits to represent can be done in 4 base
> 62 digits (10 numerals, 26 lower case, 26 upper case).
### Why create it
traditional base64 has a few issues that aren't couchdb friendly
- contains the '/' character (gets url-encoded when used as a document id)
- character table is not ordered the same as ascii, which conflicts with the
[goal of allocating sequential ids](https://eager.io/blog/how-long-does-an-id-need-to-be/#locality).
_I couldn't find why base64's character table is ordered the way it is - please enlighten me!_
`couchdb-base64` solves the above two points by using [unreserved characters (rfc 3986)](https://tools.ietf.org/html/rfc3986#section-2.3) '.' and '-' as
alternatives to '+' and '/'. It also orders these characters to match
ascii ordering.
### Install
npm install couchdb-base64
### Character set used
`-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`
### Simple example
```js
const couchdbBase64 = require('couchdb-base64')
const timestamp = 123456
const encodedTimestamp = couchdbBase64.encodeFromUInt({
uint: timestamp,
totalBits: 24
}),
assert(encodedTimestamp === '-S7-')
//
// The binary math
//
// '-' = 0
// 'S' = 30 * (64 ** 2) = 122880
// '7' = 9 * (64 ** 1) = 576
// '-' = 0
// 122880 + 576 = 123456
//
const decoded = couchdbBase64.decodeToUInt(encodedTimestamp)
assert(decoded === timestamp)
```
### API
`const couchdbBase64 = require('couchdb-base64')`
The default export holds an object with four methods
_Note: The arguments to these methods are strongly validated prior to running
operations on them. Due to the low level nature of this library I wanted to
ensure nobody passed values which didn't match the intended use-case_
#### `encodeFromUInt({ uint: , totalBits: }) -> couchdb base64 string`
Encodes the passed uint, zero padded to `totalBits`
Arguments
- **uint** is an unsigned integer less than `Number.MAX_SAFE_INTEGER`
- **totalBits** is a positive integer divisible by 6 (the number of bits which
represent a base64 character). totalBits allows you to pad your encoded
value so the document id can remain incremental. Because of this, if the
uint passed takes more bits to represent than `totalBits`, an error is thrown
as it is likely a bug.
#### `decodeToUInt(couchdbBase64String) -> uint`
Decodes the passed couchdb-base64 string to an unsigned integer
Arguments
- **couchdbBase64String** a non-empty, valid couchdb-base64 string. If it
resolves to a uint larger than Number.MAX_SAFE_INTEGER then an error is
thrown.
#### `encodeFromString(nonEmptyString) -> couchdb base64 string`
Encodes the passed string into its couchdb base64 equivalent
_Note: This library was originally built to transform uints such as timestamps
and random numbers to shorter base64 strings. I came across a need to transform
arbitrary strings into url friendly ids which is why I created this method, but
for the most part the uint <--> base64 conversions should be used._
#### `decodeToString(couchdbBase64String) -> string`
Decodes the passed couchdb base64 string into its original value
#### `isCouchdbBase64String(anyString) -> boolean`
Returns whether the the passed string is non-empty and contains only characters
in the couchdb-base64 character set. Specifically it tests against this
regex `/^[0-9A-Za-z-.]+$/`
### Test
`./run test`