@lumjs/encode 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/README.md +18 -0
- package/TODO.md +3 -0
- package/jsdoc.json +33 -0
- package/lib/base64.js +55 -0
- package/lib/base91.js +190 -0
- package/lib/crypto/index.js +171 -0
- package/lib/crypto/load.js +344 -0
- package/lib/hash.js +244 -0
- package/lib/index.js +53 -0
- package/lib/safe64/common.js +40 -0
- package/lib/safe64/header.js +142 -0
- package/lib/safe64/index.js +466 -0
- package/lib/safe64/json.js +12 -0
- package/lib/safe64/php.js +15 -0
- package/lib/safe64/settings.js +85 -0
- package/lib/safe64/ubjson.js +23 -0
- package/lib/util.js +190 -0
- package/package.json +39 -0
- package/ub-dev.js +11 -0
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// UBJSON plugin
|
|
2
|
+
const UB = require('@shelacek/ubjson');
|
|
3
|
+
const WordArray = require('../crypto').WordArray;
|
|
4
|
+
const w2b = require('../util').wordArrayToUint8Array;
|
|
5
|
+
|
|
6
|
+
module.exports =
|
|
7
|
+
{
|
|
8
|
+
encode(data)
|
|
9
|
+
{
|
|
10
|
+
const buffer = UB.encode(data, this.ubEncOpts);
|
|
11
|
+
return WordArray.create(buffer);
|
|
12
|
+
},
|
|
13
|
+
decode(opts)
|
|
14
|
+
{
|
|
15
|
+
const wordArray = this.$decodeValue(opts, false);
|
|
16
|
+
const byteArray = w2b(wordArray);
|
|
17
|
+
//console.debug({wordArray,byteArray});
|
|
18
|
+
const arrayBuffer = byteArray.buffer;
|
|
19
|
+
const decoded = UB.decode(arrayBuffer, this.ubDecOpts);
|
|
20
|
+
return decoded;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
package/lib/util.js
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Low-level encoding utilities
|
|
3
|
+
* @module @lumjs/encode/util
|
|
4
|
+
*/
|
|
5
|
+
const {N} = require('@lumjs/core/types');
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Return the ASCII/Unicode number for a character.
|
|
9
|
+
*
|
|
10
|
+
* Originally extracted from `phpjs`, which has been deprecated and replaced by
|
|
11
|
+
* [locutus](https://locutus.io/)
|
|
12
|
+
* which has a bunch of different programming language standard libraries.
|
|
13
|
+
* While I'd normally just add the library to the dependency list, I think
|
|
14
|
+
* including a `4.2 MB` library for a *single function* is overkill.
|
|
15
|
+
*
|
|
16
|
+
* @param {string} string
|
|
17
|
+
* @returns {number}
|
|
18
|
+
*/
|
|
19
|
+
exports.ord = function (string)
|
|
20
|
+
{
|
|
21
|
+
// discuss at: https://locutus.io/php/ord/
|
|
22
|
+
// original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
|
|
23
|
+
// bugfixed by: Onno Marsman
|
|
24
|
+
// improved by: Brett Zamir (http://brett-zamir.me)
|
|
25
|
+
// input by: incidence
|
|
26
|
+
// example 1: ord('K');
|
|
27
|
+
// returns 1: 75
|
|
28
|
+
// example 2: ord('\uD800\uDC00'); // surrogate pair to create a single Unicode character
|
|
29
|
+
// returns 2: 65536
|
|
30
|
+
|
|
31
|
+
var str = string + '',
|
|
32
|
+
code = str.charCodeAt(0);
|
|
33
|
+
if (0xD800 <= code && code <= 0xDBFF)
|
|
34
|
+
{
|
|
35
|
+
// High surrogate (could change last hex to 0xDB7F to treat high private surrogates as single characters)
|
|
36
|
+
var hi = code;
|
|
37
|
+
if (str.length === 1)
|
|
38
|
+
{
|
|
39
|
+
// This is just a high surrogate with no following low surrogate, so we return its value;
|
|
40
|
+
return code;
|
|
41
|
+
// we could also throw an error as it is not a complete character, but someone may want to know
|
|
42
|
+
}
|
|
43
|
+
var low = str.charCodeAt(1);
|
|
44
|
+
return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000;
|
|
45
|
+
}
|
|
46
|
+
if (0xDC00 <= code && code <= 0xDFFF)
|
|
47
|
+
{
|
|
48
|
+
// Low surrogate
|
|
49
|
+
// This is just a low surrogate with no preceding high surrogate, so we return its value;
|
|
50
|
+
return code;
|
|
51
|
+
// we could also throw an error as it is not a complete character, but someone may want to know
|
|
52
|
+
}
|
|
53
|
+
return code;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Convert a numeric string into an array of byte values for encoding purposes.
|
|
58
|
+
*
|
|
59
|
+
* @param {string} numStr - The numeric string
|
|
60
|
+
* @param {(object|number)} [options] Options
|
|
61
|
+
*
|
|
62
|
+
* If this is a `number` then it's assumed to be `options.size`.
|
|
63
|
+
*
|
|
64
|
+
* @param {number} [options.size=2] The number of characters in each number.
|
|
65
|
+
*
|
|
66
|
+
* With the default `size` of `2` and the default `base` of `16`, this
|
|
67
|
+
* will turn the numeric string `0FD4` into `[15,212]`.
|
|
68
|
+
* If you change `len` to `1`, the same string would become `[0,15,13,4]`.
|
|
69
|
+
*
|
|
70
|
+
* @param {number} [options.base=16] The numeric base for the string.
|
|
71
|
+
*
|
|
72
|
+
* This defaults to `16` which is Hexadecimal.
|
|
73
|
+
*
|
|
74
|
+
* @param {boolean} [options.strict=false] Do not allow indivisible strings
|
|
75
|
+
*
|
|
76
|
+
* If this is `true` and the length of `numStr` is not divisible by
|
|
77
|
+
* `options.size`, then a `RangeError` will be thrown.
|
|
78
|
+
*
|
|
79
|
+
* This takes priority over the `options.pad` option.
|
|
80
|
+
*
|
|
81
|
+
* @param {boolean} [options.pad=false] Pad indivisible strings
|
|
82
|
+
*
|
|
83
|
+
* If this is `true` and the length of `numStr` is not divisible by
|
|
84
|
+
* `options.size`, then the string will be padded with leading `0`s
|
|
85
|
+
* to make it divisible.
|
|
86
|
+
*
|
|
87
|
+
* If both this and `options.strict` are `false` (the default),
|
|
88
|
+
* then the string will be extracted in bytes of `options.size` for
|
|
89
|
+
* as many blocks as it is cleanly divisible, then the remainder of
|
|
90
|
+
* the string will be parsed regardless of its length.
|
|
91
|
+
*
|
|
92
|
+
* @returns {Array} An array of integers.
|
|
93
|
+
*/
|
|
94
|
+
exports.numByteArray = function (numStr, options={})
|
|
95
|
+
{
|
|
96
|
+
if (typeof options === N)
|
|
97
|
+
{
|
|
98
|
+
options = {size: options};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const numOpt = (name, defval, min, max) =>
|
|
102
|
+
{
|
|
103
|
+
const optval = options[name];
|
|
104
|
+
if (typeof optval !== N)
|
|
105
|
+
{ // Was not a number, skip it.
|
|
106
|
+
return defval;
|
|
107
|
+
}
|
|
108
|
+
if (optval < min)
|
|
109
|
+
{ // Value was lower than minimum.
|
|
110
|
+
throw new RangeError(`${name} value ${optval} is less than ${min}`);
|
|
111
|
+
}
|
|
112
|
+
if (max !== 0 && optval > max)
|
|
113
|
+
{ // Value was higher than maximum.
|
|
114
|
+
throw new RangeError(`${name} value ${optval} is more than ${max}`);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
return optval;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
const len = numOpt('size', 2, 1, 0);
|
|
121
|
+
const base = numOpt('base', 16, 2, 36);
|
|
122
|
+
|
|
123
|
+
let strLen = numStr.length;
|
|
124
|
+
let remainder = strLen % len;
|
|
125
|
+
|
|
126
|
+
if (options.strict && remainder !== 0)
|
|
127
|
+
{
|
|
128
|
+
throw new RangeError(`string length ${strLen} is not divisible by ${len}`);
|
|
129
|
+
}
|
|
130
|
+
else if (options.pad && remainder !== 0)
|
|
131
|
+
{
|
|
132
|
+
const padSize = len - remainder;
|
|
133
|
+
numStr = numStr.padStart(strLen+padSize, '0');
|
|
134
|
+
strLen = numStr.length;
|
|
135
|
+
remainder = strLen % len;
|
|
136
|
+
if (remainder !== 0)
|
|
137
|
+
{ // Something is wrong in the universe...
|
|
138
|
+
console.debug({numStr, strLen, len, remainder, arguments});
|
|
139
|
+
throw new Error("string has remainder after padding");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
const endOf = strLen - (len-1);
|
|
144
|
+
const bytes = [];
|
|
145
|
+
|
|
146
|
+
const getBytes = (a,b) => bytes.push(parseInt(numStr.substring(a, b), base));
|
|
147
|
+
|
|
148
|
+
for(let i=0; i < endOf; i+=len)
|
|
149
|
+
{
|
|
150
|
+
getBytes(i, i+len);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if (remainder !== 0)
|
|
154
|
+
{
|
|
155
|
+
getBytes(strLen - remainder, strLen);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return bytes;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Convert a `WordArray` object into a Uint8Array
|
|
163
|
+
*
|
|
164
|
+
* @param {WordArray} wordArray
|
|
165
|
+
* @returns {Uint8Array}
|
|
166
|
+
*/
|
|
167
|
+
exports.wordArrayToUint8Array = function(wordArray)
|
|
168
|
+
{
|
|
169
|
+
const l = wordArray.sigBytes;
|
|
170
|
+
const words = wordArray.words;
|
|
171
|
+
const result = new Uint8Array(l);
|
|
172
|
+
var i=0 /*dst*/, j=0 /*src*/;
|
|
173
|
+
while(true) {
|
|
174
|
+
// here i is a multiple of 4
|
|
175
|
+
if (i==l)
|
|
176
|
+
break;
|
|
177
|
+
var w = words[j++];
|
|
178
|
+
result[i++] = (w & 0xff000000) >>> 24;
|
|
179
|
+
if (i==l)
|
|
180
|
+
break;
|
|
181
|
+
result[i++] = (w & 0x00ff0000) >>> 16;
|
|
182
|
+
if (i==l)
|
|
183
|
+
break;
|
|
184
|
+
result[i++] = (w & 0x0000ff00) >>> 8;
|
|
185
|
+
if (i==l)
|
|
186
|
+
break;
|
|
187
|
+
result[i++] = (w & 0x000000ff);
|
|
188
|
+
}
|
|
189
|
+
return result;
|
|
190
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@lumjs/encode",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"main": "lib/index.js",
|
|
5
|
+
"exports":
|
|
6
|
+
{
|
|
7
|
+
".": "./lib/index.js",
|
|
8
|
+
"./base64": "./lib/base64.js",
|
|
9
|
+
"./base91": "./lib/base91.js",
|
|
10
|
+
"./crypto": "./lib/crypto/index.js",
|
|
11
|
+
"./crypto/load": "./lib/crypto/load.js",
|
|
12
|
+
"./hash": "./lib/hash.js",
|
|
13
|
+
"./safe64": "./lib/safe64/index.js",
|
|
14
|
+
"./safe64/header": "./lib/safe64/header.js",
|
|
15
|
+
"./util": "./lib/util.js",
|
|
16
|
+
"./package.json": "./package.json"
|
|
17
|
+
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"repository":
|
|
20
|
+
{
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "https://github.com/supernovus/lum.encode.js.git"
|
|
23
|
+
},
|
|
24
|
+
"dependencies": {
|
|
25
|
+
"@lumjs/core": "^1.5.1",
|
|
26
|
+
"crypto-js": "^4.1.1",
|
|
27
|
+
"php-serialize": "^4.0.2",
|
|
28
|
+
"@shelacek/ubjson": "^1.1.1"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies":
|
|
31
|
+
{
|
|
32
|
+
"@lumjs/tests": "^1.7.0"
|
|
33
|
+
},
|
|
34
|
+
"scripts":
|
|
35
|
+
{
|
|
36
|
+
"test": "node ./node_modules/@lumjs/tests/bin/lumtest.js",
|
|
37
|
+
"build-docs": "jsdoc -c ./jsdoc.json"
|
|
38
|
+
}
|
|
39
|
+
}
|
package/ub-dev.js
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const UB = require('@shelacek/ubjson');
|
|
4
|
+
|
|
5
|
+
const data = {hello:["world","darkness my old friend"]};
|
|
6
|
+
const ubj = UB.encode(data);
|
|
7
|
+
|
|
8
|
+
console.log("Size:", ubj.byteLength);
|
|
9
|
+
const utf8 = new TextDecoder().decode(ubj);
|
|
10
|
+
console.log("UTF-8:", utf8);
|
|
11
|
+
console.log("JSON:", JSON.stringify(utf8));
|