Compare commits

..

No commits in common. "f2f853c0ff7fde577c462ea58289a5d50e7dfbcf" and "0ac3d26b021f068bc73b4ecdf972b2c8d505984d" have entirely different histories.

10 changed files with 185 additions and 8171 deletions

View File

@ -1,7 +0,0 @@
[*]
insert_final_newline = true
[{*.js,*.json}]
charset = utf-8
indent_style = space
indent_size = 2

2
.gitignore vendored
View File

@ -46,5 +46,3 @@ Network Trash Folder
Temporary Items Temporary Items
.apdisk .apdisk
node_modules node_modules
coverage
dist

View File

@ -1,2 +0,0 @@
*
!dist/**/*

View File

@ -37,53 +37,39 @@ npm install base1
## Usage ## Usage
```js ```js
import { encodeL, encode, decodeL, decode } from 'base1' var base1 = require("base1");
const uint8Array = Uint8Array.from([0x03, 0xC0]) var buf = new Buffer([0x03, 0xC0]);
const l = encodeL(uint8Array) // 1217n var l = base1.encodeL(buf); // 1217
const str = encode(uint8Array) // "AAAAAAAAAAAA...AA", string is 1,217 characters long var str = base1.encode(buf); // "AAAAAAAAAAAA...AA", string is 1,217 characters long
const uint8Array2 = decode(str) // Uint8Array [ 3, 192 ] var buf2 = base1.decode(str); // <Buffer 03 c0>
const uint8Array3 = decodeL(l) // Uint8Array [ 3, 192 ] var buf3 = base1.decodeL(l); // <Buffer 03 c0>
```
### In the browser
Load this file in the browser to gain access to a `base1` global.
```html
<script src="https://unpkg.com/base1" crossorigin></script>
<script>
console.log(base1.decode('AAAAAAAAAAAAAAAAAAAAAAAAAA'))
</script>
``` ```
## API ## API
`base1` 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: ### base1.encodeL(buf)
```js Input a `Buffer`. Returns a Base1 string length (i.e. a non-negative integer). If this number cannot be represented as a JavaScript number, which is increasingly likely as buffer length increases, returns a string containing its decimal digits.
const buffer = Buffer.from(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength)
```
### encodeL(uint8Array) * The first buffer for which a string is returned is the 7-byte sequence 0x1E 0xFE 0xFE 0xFE 0xFE 0xFF 0x00, which returns the string `"9007199254740993"`.
* The last buffer for which a number is returned is the 128-byte sequence 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xF6 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFE 0xFF 0x00, which returns `Number.MAX_VALUE` = 2<sup>1024</sup> - 2<sup>971</sup> = 179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858369.
Input a `Uint8Array`. Returns a Base1 string length, in the form of a BigInt. ### base1.encode(buf)
### encode(uint8Array) Encodes a `Buffer` as a Base1 string. This method calls `base1.encodeL` to get a length `l` and then returns a string which is `l` repetitions of "A" in a row.
Encodes a `Uint8Array` as a Base1 string. This method calls `base1.encodeL` to get a length `l` and then returns a string which is `l` repetitions of "A" in a row. JavaScript specifies no maximum length for a string, although MDN's polyfill for [`String.prototype.repeat`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/repeat) gives an upper limit of 2<sup>28</sup> - 1 = 268,435,455 characters. This is equivalent to the 4-byte sequence 0x0E 0xFE 0xFE 0xFE. Buffers which are longer or lexicographically greater than this may cause errors in your JavaScript engine.
JavaScript does not specify, nor does `base1` enforce, a maximum length for a string. However, MDN's polyfill for [`String.prototype.repeat`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/repeat) gives an upper limit of 2<sup>28</sup> - 1 = 268,435,455 characters. This is equivalent to the 4-byte sequence 0x0E 0xFE 0xFE 0xFE. Buffers which are longer or lexicographically greater than this may cause errors in your JavaScript engine. ### base1.decodeL(l)
### decodeL(l) Take a Base1 string length in the form of a non-negative integer, a non-negative integer expressed as a decimal string or a `big-integer` object and return the `Buffer` it represents.
Take a Base1 string length in the form of a BigInt and return a `Uint8Array` containing the data which it represents. ### base1.decode(str)
### decode(str) Decode a Base1 string and return the `Buffer` it represents.
Decode a Base1 string and return a `Uint8Array` containing the data which it represents.
## Ports ## Ports

90
index.js Normal file
View File

@ -0,0 +1,90 @@
/**
Converts binary data to and from Base1, whereby the original binary is
converted to an integer `n` and then a string of `n` repetitions of "A".
E.g. base1.encode(new Buffer([17])) = "AAAAAAAAAAAAAAAAAA".
*/
var bigInteger = require("big-integer");
var base = bigInteger(1 << 8);
module.exports = {
/** Encode a buffer as a length `l` */
encodeL: function(buf) {
// First turn binary data into an integer
var l = bigInteger(0);
for(var i = 0; i < buf.length; i++) {
var b = buf[i];
l = l.times(base).plus(b);
}
// Next we need to determine the block.
// Binary of length 0 bytes gives Base1 of length 0 ("")
// Binary of length 1 byte gives Base1 of length 1 ("A") to 256 inclusive
// Binary of length 2 bytes gives Base1 of length 257 to 65792 inclusive
// etc.
var binaryLength = 0, blockSize = base.pow(binaryLength);
while(binaryLength < buf.length) {
l = l.plus(blockSize);
binaryLength++;
blockSize = blockSize.times(base);
}
var number = l.toJSNumber(); // This may lose information.
if (bigInteger(number.toString(2), 2).equals(l)) {
return number;
}
return l.toString(10);
},
encode: function(buf) {
return "A".repeat(this.encodeL(buf));
},
/** Operates on a length `l` */
decodeL: function(l) {
if(typeof l === 'number' && l > Number.MAX_SAFE_INTEGER) {
// Apparently `bigInteger` does not preserve all the decimal digits! So
// use this hack at construction time
l = bigInteger(l.toString(2), 2);
} else {
l = bigInteger(l);
}
// First we need to work out the length in bytes of the original binary.
// Base1 of length 0 ("") means binary is 0 bytes long.
// Base1 of length 1 ("A") to 256 inclusive means binary is 1 byte long.
// Base1 of length 257 to 65792 inclusive means binary is 2 bytes long.
// Base1 of length 65793 to 16843008 inclusive means binary is 3 bytes long.
// etc.
var binaryLength = 0, blockSize = base.pow(binaryLength);
while(l.greaterOrEquals(blockSize)) {
l = l.minus(blockSize);
binaryLength++;
blockSize = blockSize.times(base);
}
// `l` is now the offset into the block, a number from 0 to
// 256 ** `binaryLength` - 1 inclusive. We can populate the buffer from the
// number now.
var buf = new Buffer(binaryLength);
for(var byteNum = binaryLength - 1; byteNum >= 0; byteNum--) {
var b = l.mod(base);
buf[byteNum] = b.toJSNumber();
l = l.minus(b).divide(base);
}
return buf;
},
decode: function(base1) {
// Got to make sure every character is "A". TODO: PERFORMANCE???
var l = base1.length;
for(var i = 0; i < l; i++) {
if(base1.charAt(i) !== "A") {
throw new Error("This is not a valid Base1 string");
}
}
return this.decodeL(l);
}
};

7940
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,15 +1,13 @@
{ {
"name": "base1", "name": "base1",
"version": "1.0.1", "version": "0.1.0",
"description": "Convert binary data to Base1", "description": "Convert binary data to Base1",
"homepage": "https://github.com/qntm/base1", "homepage": "https://github.com/qntm/base1",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git://github.com/qntm/base1.git" "url": "git://github.com/qntm/base1.git"
}, },
"module": "dist/es6/base1.js", "main": "index.js",
"main": "dist/cjs/base1.js",
"browser": "dist/iife/base1.js",
"keywords": [ "keywords": [
"base64", "base64",
"base1", "base1",
@ -20,28 +18,11 @@
"silly" "silly"
], ],
"scripts": { "scripts": {
"build": "rollup -c rollup.config.js", "test": "node test/test.js"
"jest": "jest",
"rollup": "rollup",
"standard": "standard",
"test": "standard && jest --coverage"
}, },
"author": "qntm", "author": "qntm",
"license": "MIT", "license": "MIT",
"dependencies": {}, "dependencies": {
"devDependencies": { "big-integer": "^1.6.23"
"@babel/preset-env": "^7.7.7",
"glob": "^7.1.6",
"jest": "^25.1.0",
"rollup": "^1.29.0",
"standard": "^14.3.1"
},
"babel": {
"presets": [
"@babel/preset-env"
]
},
"standard": {
"ignore": "dist"
} }
} }

View File

@ -1,23 +0,0 @@
module.exports = [{
// nearly indistinguishable from a copy and paste of the source
input: 'src/index.js',
output: {
file: 'dist/es6/base1.js',
format: 'esm'
}
}, {
// same as above but Node.js-friendly
input: 'src/index.js',
output: {
file: 'dist/cjs/base1.js',
format: 'cjs'
}
}, {
// this can be imported into the browser as a script
input: 'src/index.js',
output: {
file: 'dist/iife/base1.js',
format: 'iife',
name: 'base1'
}
}]

View File

@ -1,44 +0,0 @@
/**
Converts binary data to and from Base1, whereby the original binary is
converted to a BigInt `l` and then a string of `l` repetitions of "A".
E.g. base1.encode(new Buffer([17])) = "AAAAAAAAAAAAAAAAAA".
*/
/* global BigInt */
export const encodeL = uint8Array =>
uint8Array.reduce((l, b) => l * 256n + BigInt(b) + 1n, 0n)
export const encode = uint8Array => {
const l = encodeL(uint8Array)
// String.prototype.repeat demands a number, not a BigInt
const number = Number(l) // This can lose information
if (BigInt(number) !== l) {
throw Error('Could not compute the Base1 output length as a number')
}
// This could still throw, JS specifies no string length limit
return 'A'.repeat(number)
}
export const decodeL = l => {
const bytes = []
while (l > 0n) {
l -= 1n
bytes.push(Number(l % 256n))
l /= 256n
}
bytes.reverse()
return Uint8Array.from(bytes)
}
export const decode = base1 => {
// TODO: performance?
if (!/^A*$/.test(base1)) {
throw Error('This is not a valid Base1 string')
}
return decodeL(BigInt(base1.length))
}

View File

@ -1,113 +1,88 @@
/** Tests for base65536, ensure strings survive round trips, etc. */ /** Tests for base65536, ensure strings survive round trips, etc. */
/* eslint-env jest */ var base1 = require("../index.js");
/* global BigInt */ var fs = require("fs");
import fs from 'fs' console.log(base1.encodeL(new Buffer([ ])) === 0);
import { encodeL, encode, decodeL, decode } from '../src/index' console.log(base1.encodeL(new Buffer([ 0])) === 1);
console.log(base1.encodeL(new Buffer([ 17])) === 18);
console.log(base1.encodeL(new Buffer([ 255])) === 256);
console.log(base1.encodeL(new Buffer([ 0, 0])) === 257);
console.log(base1.encodeL(new Buffer([ 255, 255])) === 65792);
console.log(base1.encodeL(new Buffer([ 0, 0, 0])) === 65793);
console.log(base1.encodeL(new Buffer([ 255, 255, 255])) === 16843008);
console.log(base1.encodeL(new Buffer([0, 0, 0, 0])) === 16843009);
describe('base1', () => { console.log(base1.decodeL( 0).equals(new Buffer([ ])));
describe('encodeL and decodeL', () => { console.log(base1.decodeL( 1).equals(new Buffer([ 0])));
describe('encodeL', () => { console.log(base1.decodeL( 18).equals(new Buffer([ 17])));
it('works', () => { console.log(base1.decodeL( 256).equals(new Buffer([ 255])));
expect(encodeL(Uint8Array.from([]))).toBe(0n) console.log(base1.decodeL( 257).equals(new Buffer([ 0, 0])));
expect(encodeL(Uint8Array.from([0]))).toBe(1n) console.log(base1.decodeL( 65792).equals(new Buffer([ 255, 255])));
expect(encodeL(Uint8Array.from([17]))).toBe(18n) console.log(base1.decodeL( 65793).equals(new Buffer([ 0, 0, 0])));
expect(encodeL(Uint8Array.from([255]))).toBe(256n) console.log(base1.decodeL(16843008).equals(new Buffer([ 255, 255, 255])));
expect(encodeL(Uint8Array.from([0, 0]))).toBe(257n) console.log(base1.decodeL(16843009).equals(new Buffer([0, 0, 0, 0])));
expect(encodeL(Uint8Array.from([255, 255]))).toBe(65792n)
expect(encodeL(Uint8Array.from([0, 0, 0]))).toBe(65793n)
expect(encodeL(Uint8Array.from([255, 255, 255]))).toBe(16843008n)
expect(encodeL(Uint8Array.from([0, 0, 0, 0]))).toBe(16843009n)
})
it('edge cases', () => { // Edge cases for encodeL and decodeL
expect(encodeL(Uint8Array.from([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE]))).toBe(BigInt(Number.MAX_SAFE_INTEGER)) console.log(base1.encodeL(new Buffer([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE])) === Number.MAX_SAFE_INTEGER);
expect(encodeL(Uint8Array.from([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE]))).toBe(9007199254740991n) console.log(base1.encodeL(new Buffer([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE])) === 9007199254740991);
expect(encodeL(Uint8Array.from([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF]))).toBe(9007199254740992n) console.log(base1.encodeL(new Buffer([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF])) === 9007199254740992);
expect(encodeL(Uint8Array.from([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x00]))).toBe(9007199254740993n) console.log(base1.encodeL(new Buffer([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x00])) === "9007199254740993");
// One below Number.MAX_VALUE // One below Number.MAX_VALUE - cannot be represented as a number. Returns a string.
expect(encodeL(Uint8Array.from([0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xF6, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE]))).toBe(BigInt(Number.MAX_VALUE) - 1n) console.log(base1.encodeL(new Buffer([0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xF6, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE])) !== Number.MAX_VALUE);
console.log(base1.encodeL(new Buffer([0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xF6, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE])) === "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858367");
// Exactly Number.MAX_VALUE // Exactly Number.MAX_VALUE
expect(encodeL(Uint8Array.from([0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xF6, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF]))).toBe(BigInt(Number.MAX_VALUE)) console.log(base1.encodeL(new Buffer([0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xF6, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF])) === Number.MAX_VALUE);
console.log(base1.encodeL(new Buffer([0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xF6, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF])) !== "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368");
// One above Number.MAX_VALUE // One above Number.MAX_VALUE
expect(encodeL(Uint8Array.from([0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xF6, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x00]))).toBe(BigInt(Number.MAX_VALUE) + 1n) console.log(base1.encodeL(new Buffer([0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xF6, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x00])) !== Number.MAX_VALUE);
}) console.log(base1.encodeL(new Buffer([0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xF6, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x00])) === "179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858369");
})
describe('decodeL', () => { console.log(base1.decodeL(Number.MAX_SAFE_INTEGER).equals(new Buffer([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE])));
it('works', () => { console.log(base1.decodeL(9007199254740991).equals(new Buffer([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE])));
expect(decodeL(0n)).toEqual(Uint8Array.from([])) console.log(base1.decodeL(9007199254740992).equals(new Buffer([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF])));
expect(decodeL(1n)).toEqual(Uint8Array.from([0])) console.log(base1.decodeL("9007199254740992").equals(new Buffer([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF])));
expect(decodeL(18n)).toEqual(Uint8Array.from([17])) console.log(base1.decodeL("9007199254740993").equals(new Buffer([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x00])));
expect(decodeL(256n)).toEqual(Uint8Array.from([255]))
expect(decodeL(257n)).toEqual(Uint8Array.from([0, 0]))
expect(decodeL(65792n)).toEqual(Uint8Array.from([255, 255]))
expect(decodeL(65793n)).toEqual(Uint8Array.from([0, 0, 0]))
expect(decodeL(16843008n)).toEqual(Uint8Array.from([255, 255, 255]))
expect(decodeL(16843009n)).toEqual(Uint8Array.from([0, 0, 0, 0]))
})
it('edge cases', () => { console.log(base1.decodeL(Number.MAX_VALUE).equals(new Buffer([0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xF6, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF])));
expect(decodeL(BigInt(Number.MAX_SAFE_INTEGER))).toEqual(Uint8Array.from([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE]))
expect(decodeL(9007199254740991n)).toEqual(Uint8Array.from([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE]))
expect(decodeL(9007199254740992n)).toEqual(Uint8Array.from([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF]))
expect(decodeL(9007199254740993n)).toEqual(Uint8Array.from([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x00]))
expect(decodeL(BigInt(Number.MAX_VALUE))).toEqual(Uint8Array.from([0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xF6, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF])) console.log(base1.decodeL("0").equals(new Buffer([])));
}) console.log(base1.decodeL(base1.encodeL(Buffer.alloc(10, 1))).equals(Buffer.alloc(10, 1)));
}) console.log(base1.decodeL(base1.encodeL(Buffer.alloc(100, 1))).equals(Buffer.alloc(100, 1)));
console.log(base1.decodeL(base1.encodeL(Buffer.alloc(1000, 1))).equals(Buffer.alloc(1000, 1)));
console.log(base1.decodeL(base1.encodeL(Buffer.alloc(10000, 1))).equals(Buffer.alloc(10000, 1)));
console.log();
describe('round trips', () => { // encode, decode
it('work', () => {
expect(decodeL(encodeL(new Uint8Array(10).fill(1)))).toEqual(new Uint8Array(10).fill(1))
expect(decodeL(encodeL(new Uint8Array(100).fill(1)))).toEqual(new Uint8Array(100).fill(1))
expect(decodeL(encodeL(new Uint8Array(1000).fill(1)))).toEqual(new Uint8Array(1000).fill(1))
expect(decodeL(encodeL(new Uint8Array(10000).fill(1)))).toEqual(new Uint8Array(10000).fill(1))
})
})
})
describe('encode and decode', () => { var pairsDir = "./test/pairs";
describe('encode', () => { fs.readdirSync(pairsDir).forEach(function(fileName) {
it('throws on a bad BigInt length', () => { if(!fileName.endsWith(".base1")) {
expect(() => encode(Uint8Array.from([0x1E, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x00]))).toThrowError('Could not compute the Base1 output length as a number') return;
}) }
var caseName = fileName.substring(0, fileName.length - ".base1".length);
var base1Text = fs.readFileSync(pairsDir + "/" + caseName + ".base1", "utf8");
var binary = fs.readFileSync(pairsDir + "/" + caseName + ".bin");
console.log(base1.decode(base1Text).equals(binary));
console.log(base1.encode(binary) === base1Text);
});
it('throws on too large an input', () => { var badDir = "./test/bad";
expect(() => encode(Uint8Array.from([0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xF6, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF]))).toThrowError('Invalid string length') fs.readdirSync(badDir).forEach(function(fileName) {
}) if(!fileName.endsWith(".base1")) {
}) return;
}
var caseName = fileName.substring(0, fileName.length - ".base1".length);
var base1Text = fs.readFileSync(badDir + "/" + caseName + ".base1", "utf8");
try {
base1.decode(base1Text);
console.log(false);
} catch(e) {
console.log(true);
}
});
describe('round trips', () => { console.log("OK");
const pairsDir = './test/pairs'
fs.readdirSync(pairsDir)
.filter(fileName => fileName.endsWith('.base1'))
.forEach(fileName => {
const caseName = fileName.substring(0, fileName.length - '.base1'.length)
it(caseName, () => {
const base1 = fs.readFileSync(pairsDir + '/' + caseName + '.base1', 'utf8')
const binary = Uint8Array.from(fs.readFileSync(pairsDir + '/' + caseName + '.bin'))
expect(decode(base1)).toEqual(binary)
expect(encode(binary)).toBe(base1)
})
})
})
describe('invalid Base1', () => {
const badDir = './test/bad'
fs.readdirSync(badDir)
.filter(fileName => fileName.endsWith('.base1'))
.forEach(fileName => {
const caseName = fileName.substring(0, fileName.length - '.base1'.length)
it(caseName, () => {
const base1 = fs.readFileSync(badDir + '/' + caseName + '.base1', 'utf8')
expect(() => decode(base1)).toThrowError('This is not a valid Base1 string')
})
})
})
})
})