Skip to content

Commit 17cf2eb

Browse files
committed
Added multibase encoding and decoding feature and testing
1 parent 49f6111 commit 17cf2eb

7 files changed

+629
-2014
lines changed

package-lock.json

+565-2,011
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,17 @@
2323
"uuid": "^8.3.2"
2424
},
2525
"devDependencies": {
26-
"@types/jest": "^26.0.20",
26+
"@types/jest": "^27.0.2",
2727
"@types/node": "^14.14.35",
2828
"@types/node-forge": "^0.10.4",
2929
"@typescript-eslint/eslint-plugin": "^4.12.0",
3030
"@typescript-eslint/parser": "^4.12.0",
3131
"eslint": "^7.17.0",
3232
"eslint-config-prettier": "^7.1.0",
3333
"eslint-plugin-prettier": "^3.3.1",
34-
"jest": "^26.6.3",
34+
"jest": "^27.2.5",
3535
"prettier": "^2.2.1",
36-
"ts-jest": "^26.4.4",
36+
"ts-jest": "^27.0.5",
3737
"ts-node": "^9.1.1",
3838
"tsconfig-paths": "^3.9.0",
3939
"typedoc": "^0.21.5",

src/utils.ts

+29
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
import type { Codec } from 'multiformats/bases/base';
2+
13
import crypto from 'crypto';
24
import { performance } from 'perf_hooks';
5+
import { bases } from 'multiformats/basics';
36

47
/**
58
* Gets random bytes as Uint8Array
@@ -82,6 +85,28 @@ function toUUID(bytes: Uint8Array): string {
8285
].join('-');
8386
}
8487

88+
type MultibaseFormats = keyof typeof bases;
89+
90+
const basesByPrefix: Record<string, Codec<string, string>> = {};
91+
for (const k in bases) {
92+
const codec = bases[k];
93+
basesByPrefix[codec.prefix] = codec;
94+
}
95+
96+
function toMultibase(idBytes: ArrayBuffer, format: MultibaseFormats): string {
97+
const codec = bases[format];
98+
return codec.encode(new Uint8Array(idBytes));
99+
}
100+
101+
function fromMultibase(idString: string): ArrayBuffer | undefined {
102+
const prefix = idString[0];
103+
const codec = basesByPrefix[prefix];
104+
if (codec == null) {
105+
return;
106+
}
107+
return codec.decode(idString).buffer;
108+
}
109+
85110
/**
86111
* Encodes Uint8Array to hex string
87112
*/
@@ -199,6 +224,8 @@ export {
199224
timeSource,
200225
take,
201226
toUUID,
227+
toMultibase,
228+
fromMultibase,
202229
bytes2hex,
203230
hex2bytes,
204231
bytes2bin,
@@ -210,3 +237,5 @@ export {
210237
toFixedPoint,
211238
fromFixedPoint,
212239
};
240+
241+
export type { MultibaseFormats };

tests/IdDeterministic.test.ts

+8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ describe('IdDeterministic', () => {
1313
const ids = [...utils.take(idGen, 10)];
1414
expect(ids).toHaveLength(10);
1515
});
16+
test('ids can be encoded and decoded with multibase', () => {
17+
const idGen = new IdDeterministic();
18+
const id = idGen.get();
19+
const encoded = utils.toMultibase(id, 'base58btc');
20+
const id_ = utils.fromMultibase(encoded);
21+
expect(id_).toBeDefined();
22+
expect(Buffer.from(id).equals(Buffer.from(id_!))).toBe(true);
23+
});
1624
test('ids are deterministic', () => {
1725
const id = new IdDeterministic();
1826
const id1 = Buffer.from(id.get());

tests/IdRandom.test.ts

+8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ describe('IdRandom', () => {
1313
const ids = [...utils.take(idGen, 10)];
1414
expect(ids).toHaveLength(10);
1515
});
16+
test('ids can be encoded and decoded with multibase', () => {
17+
const idGen = new IdRandom();
18+
const id = idGen.get();
19+
const encoded = utils.toMultibase(id, 'base58btc');
20+
const id_ = utils.fromMultibase(encoded);
21+
expect(id_).toBeDefined();
22+
expect(Buffer.from(id).equals(Buffer.from(id_!))).toBe(true);
23+
});
1624
test('ids are random', () => {
1725
const id = new IdRandom();
1826
const count = 10;

tests/IdSortable.test.ts

+8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ describe('IdSortable', () => {
1313
const ids = [...utils.take(idGen, 10)];
1414
expect(ids).toHaveLength(10);
1515
});
16+
test('ids can be encoded and decoded with multibase', () => {
17+
const idGen = new IdSortable();
18+
const id = idGen.get();
19+
const encoded = utils.toMultibase(id, 'base58btc');
20+
const id_ = utils.fromMultibase(encoded);
21+
expect(id_).toBeDefined();
22+
expect(Buffer.from(id).equals(Buffer.from(id_!))).toBe(true);
23+
});
1624
test('ids are lexically sortable', () => {
1725
const id = new IdSortable();
1826
const i1 = Buffer.from(id.get());

tests/utils.test.ts

+8
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,12 @@ describe('utils', () => {
9696
expect(utils.toFixedPoint(0, 12, 3)).toStrictEqual([0, 0]);
9797
expect(utils.fromFixedPoint([0, 0], 12, 3)).toBe(0.0);
9898
});
99+
test('multibase encoding and decoding', () => {
100+
const bytes = new Uint8Array([123, 124]).buffer;
101+
const encoded = utils.toMultibase(bytes, 'base58btc');
102+
expect(encoded).toBe('zAQ3');
103+
const bytes_ = utils.fromMultibase(encoded);
104+
expect(bytes_).toBeDefined();
105+
expect(Buffer.from(bytes_!).equals(Buffer.from(bytes))).toBe(true);
106+
});
99107
});

0 commit comments

Comments
 (0)