Compare commits
1 Commits
developmen
...
feature/S3
Author | SHA1 | Date |
---|---|---|
vrancurel | a3307b1d80 |
|
@ -6,6 +6,10 @@
|
||||||
// - rep_group_id 07 bytes replication group identifier
|
// - rep_group_id 07 bytes replication group identifier
|
||||||
// - other_information arbitrary user input, such as a unique string
|
// - other_information arbitrary user input, such as a unique string
|
||||||
|
|
||||||
|
const base62Integer = require('base62');
|
||||||
|
const BASE62 = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
||||||
|
const base62String = require('base-x')(BASE62);
|
||||||
|
|
||||||
// the lengths of the components in bytes
|
// the lengths of the components in bytes
|
||||||
const LENGTH_TS = 14; // timestamp: epoch in ms
|
const LENGTH_TS = 14; // timestamp: epoch in ms
|
||||||
const LENGTH_SEQ = 6; // position in ms slot
|
const LENGTH_SEQ = 6; // position in ms slot
|
||||||
|
@ -152,4 +156,61 @@ function decode(str) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = { generateVersionId, getInfVid, encode, decode };
|
/* tiny version Ids constants:
|
||||||
|
*
|
||||||
|
* Note: base62Integer() cannot encode integers larger than 15 digits
|
||||||
|
* so we assume that TV_TOTAL <= 30 and we cut it in half. Please
|
||||||
|
* revisit if TV_TOTAL is greater than 30.
|
||||||
|
*/
|
||||||
|
const TV_TOTAL = LENGTH_TS + LENGTH_SEQ;
|
||||||
|
const TV_HALF = TV_TOTAL / 2;
|
||||||
|
const TV_EPAD = '0'.repeat(Math.ceil(TV_HALF * (Math.log(10) / Math.log(62))));
|
||||||
|
const TV_DPAD = '0'.repeat(TV_HALF);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encode a versionId to obscure internal information contained
|
||||||
|
* in a version ID (less than 40 bytes).
|
||||||
|
*
|
||||||
|
* @param {string} str - the versionId to encode
|
||||||
|
* @return {string} - the encoded tinyVersionId
|
||||||
|
*/
|
||||||
|
function tinyEncode(str) {
|
||||||
|
const part1 = Number(str.substring(0, TV_HALF));
|
||||||
|
const part2 = Number(str.substring(TV_HALF, TV_TOTAL));
|
||||||
|
const part3 = Buffer.from(str.substring(TV_TOTAL));
|
||||||
|
const enc1 = base62Integer.encode(part1);
|
||||||
|
const enc2 = base62Integer.encode(part2);
|
||||||
|
const enc3 = base62String.encode(part3);
|
||||||
|
return (TV_EPAD + enc1).slice(-TV_EPAD.length) +
|
||||||
|
(TV_EPAD + enc2).slice(-TV_EPAD.length) +
|
||||||
|
enc3;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode a tinyVersionId. May return an error if the input string is
|
||||||
|
* invalid hex string or results in an invalid value.
|
||||||
|
*
|
||||||
|
* @param {string} str - the encoded tinyVersionId to decode
|
||||||
|
* @return {(string|Error)} - the decoded versionId or an error
|
||||||
|
*/
|
||||||
|
function tinyDecode(str) {
|
||||||
|
try {
|
||||||
|
let start = 0;
|
||||||
|
const enc1 = str.substring(start, start + TV_EPAD.length);
|
||||||
|
const orig1 = base62Integer.decode(enc1);
|
||||||
|
start += TV_EPAD.length;
|
||||||
|
const enc2 = str.substring(start, start + TV_EPAD.length);
|
||||||
|
const orig2 = base62Integer.decode(enc2);
|
||||||
|
start += TV_EPAD.length;
|
||||||
|
const enc3 = str.substring(start);
|
||||||
|
const orig3 = base62String.decode(enc3);
|
||||||
|
return (TV_DPAD + orig1.toString()).slice(-TV_DPAD.length) +
|
||||||
|
(TV_DPAD + orig2.toString()).slice(-TV_DPAD.length) +
|
||||||
|
orig3.toString();
|
||||||
|
} catch (err) {
|
||||||
|
// in case of exceptions caused by base62 libs
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { generateVersionId, getInfVid, encode, decode, tinyEncode, tinyDecode };
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
"agentkeepalive": "^4.1.3",
|
"agentkeepalive": "^4.1.3",
|
||||||
"ajv": "6.12.2",
|
"ajv": "6.12.2",
|
||||||
"async": "~2.1.5",
|
"async": "~2.1.5",
|
||||||
|
"base62": "2.0.1",
|
||||||
|
"base-x": "3.0.8",
|
||||||
"debug": "~2.6.9",
|
"debug": "~2.6.9",
|
||||||
"diskusage": "^1.1.1",
|
"diskusage": "^1.1.1",
|
||||||
"ioredis": "4.9.5",
|
"ioredis": "4.9.5",
|
||||||
|
|
|
@ -39,4 +39,53 @@ describe('test generating versionIds', () => {
|
||||||
assert.strictEqual(vids.length, count);
|
assert.strictEqual(vids.length, count);
|
||||||
assert.deepStrictEqual(vids, decoded);
|
assert.deepStrictEqual(vids, decoded);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('simple tiny version test', () => {
|
||||||
|
const vid = '98376906954349999999RG001 145.20.5';
|
||||||
|
const encoded = VID.tinyEncode(vid);
|
||||||
|
assert.strictEqual(encoded, 'aJLWKz4Ko9IjBBgXKj5KQT2G9UHv0g7P');
|
||||||
|
const decoded = VID.tinyDecode(encoded);
|
||||||
|
assert.strictEqual(vid, decoded);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('tiny version test with smaller part1 number', () => {
|
||||||
|
const vid = '00000000054349999999RG001 145.20.5';
|
||||||
|
const encoded = VID.tinyEncode(vid);
|
||||||
|
const decoded = VID.tinyDecode(encoded);
|
||||||
|
assert.strictEqual(vid, decoded);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('tiny version test with smaller part2 number', () => {
|
||||||
|
const vid = '98376906950000099999RG001 145.20.5';
|
||||||
|
const encoded = VID.tinyEncode(vid);
|
||||||
|
const decoded = VID.tinyDecode(encoded);
|
||||||
|
assert.strictEqual(vid, decoded);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('tiny version test with smaller part3', () => {
|
||||||
|
const vid = '98376906950000099999R1 145.20.5';
|
||||||
|
const encoded = VID.tinyEncode(vid);
|
||||||
|
const decoded = VID.tinyDecode(encoded);
|
||||||
|
assert.strictEqual(vid, decoded);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('tiny version test with smaller part3 - 2', () => {
|
||||||
|
const vid = '98376906950000099999R1x';
|
||||||
|
const encoded = VID.tinyEncode(vid);
|
||||||
|
const decoded = VID.tinyDecode(encoded);
|
||||||
|
assert.strictEqual(vid, decoded);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('error case: when invalid tiny key part 3 has invalid base62 character', () => {
|
||||||
|
const invalidTinyVersionId = 'aJLWKz4Ko9IjBBgXKj5KQT.G9UHv0g7P';
|
||||||
|
const decoded = VID.tinyDecode(invalidTinyVersionId);
|
||||||
|
assert(decoded instanceof Error);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should encode and decode tiny versionIds', () => {
|
||||||
|
const encoded = vids.map(vid => VID.tinyEncode(vid));
|
||||||
|
const decoded = encoded.map(vid => VID.tinyDecode(vid));
|
||||||
|
assert.strictEqual(vids.length, count);
|
||||||
|
assert.deepStrictEqual(vids, decoded);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
17
yarn.lock
17
yarn.lock
|
@ -250,6 +250,18 @@ balanced-match@^1.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
|
||||||
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
|
||||||
|
|
||||||
|
base-x@3.0.8:
|
||||||
|
version "3.0.8"
|
||||||
|
resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d"
|
||||||
|
integrity sha512-Rl/1AWP4J/zRrk54hhlxH4drNxPJXYUaKffODVI53/dAsV4t9fBxyxYKAVPU1XBHxYwOWP9h9H0hM2MVw4YfJA==
|
||||||
|
dependencies:
|
||||||
|
safe-buffer "^5.0.1"
|
||||||
|
|
||||||
|
base62@2.0.1:
|
||||||
|
version "2.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/base62/-/base62-2.0.1.tgz#729cfe179ed34c61e4a489490105b44ce4ea1197"
|
||||||
|
integrity sha512-4t4WQK7mdbcWzqEBiq6tfo2qDCeIZGXvjifJZyxHIVcjQkZJxpFtu/pa2Va69OouCkg6izZ08hKnPxroeDyzew==
|
||||||
|
|
||||||
base64-arraybuffer@0.1.5:
|
base64-arraybuffer@0.1.5:
|
||||||
version "0.1.5"
|
version "0.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
|
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
|
||||||
|
@ -2191,6 +2203,11 @@ rx-lite@^3.1.2:
|
||||||
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
|
resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-3.1.2.tgz#19ce502ca572665f3b647b10939f97fd1615f102"
|
||||||
integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=
|
integrity sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=
|
||||||
|
|
||||||
|
safe-buffer@^5.0.1:
|
||||||
|
version "5.2.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||||
|
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||||
|
|
||||||
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
||||||
version "5.1.2"
|
version "5.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d"
|
||||||
|
|
Loading…
Reference in New Issue