@fagelsjo/blocks 0.0.1 → 0.0.2
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/Makefile +1 -1
- package/blocks.ts +337 -0
- package/index.ts +27 -0
- package/package.json +5 -1
- package/tsconfig.json +1 -1
- package/index.js +0 -12
package/Makefile
CHANGED
package/blocks.ts
ADDED
|
@@ -0,0 +1,337 @@
|
|
|
1
|
+
/* blocks.ts */
|
|
2
|
+
|
|
3
|
+
let log:(...args:any[])=>void;
|
|
4
|
+
let fail:(...args:any[])=>never;
|
|
5
|
+
|
|
6
|
+
log = console.log;
|
|
7
|
+
fail = (...args:any[]): never => {
|
|
8
|
+
console.error(...args);
|
|
9
|
+
throw new Error();
|
|
10
|
+
|
|
11
|
+
return void 0 as never;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
type BlockData = Uint16Array;
|
|
15
|
+
|
|
16
|
+
interface Block {
|
|
17
|
+
readonly data: BlockData;
|
|
18
|
+
readonly cidr: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
let mkblock:(x:string)=>Block;
|
|
22
|
+
let parse:(x:string)=>Block;
|
|
23
|
+
let bestidx:(block:Block)=>number;
|
|
24
|
+
let tostr:(block:Block)=>string;
|
|
25
|
+
let hex16:(x:number,bigendian?:boolean)=>string;
|
|
26
|
+
|
|
27
|
+
mkblock = (x:string): Block =>
|
|
28
|
+
parse(x)
|
|
29
|
+
|| fail('parse error');
|
|
30
|
+
|
|
31
|
+
//fe80::20c:29ff:fe9f:807c
|
|
32
|
+
//fe80:0000:0000:0000:0000:0000:0000:
|
|
33
|
+
// 0000:0000:0000:0000:0000:0000:020c:29ff:fe9f:807c
|
|
34
|
+
|
|
35
|
+
hex16 = (x:number,littleendian:boolean=true): string => {
|
|
36
|
+
let x_:number;
|
|
37
|
+
let a:string;
|
|
38
|
+
let b:string;
|
|
39
|
+
let c:string;
|
|
40
|
+
let d:string;
|
|
41
|
+
let a_:boolean;
|
|
42
|
+
let b_:boolean;
|
|
43
|
+
let c_:boolean;
|
|
44
|
+
let d_:boolean;
|
|
45
|
+
let nibble:number;
|
|
46
|
+
let nib2str:(y:number)=>string;
|
|
47
|
+
|
|
48
|
+
nib2str = (y:number):string =>
|
|
49
|
+
(y<10) ?
|
|
50
|
+
y.toString() :
|
|
51
|
+
(y<16) ?
|
|
52
|
+
['a','b','c','d','e','f'][(y-10)]||fail() :
|
|
53
|
+
nib2str((y&0x000f));
|
|
54
|
+
|
|
55
|
+
x_ = (x&0xffff);
|
|
56
|
+
nibble = (x_>>12); a=nib2str(nibble);
|
|
57
|
+
nibble = (x_>>8); b=nib2str(nibble);
|
|
58
|
+
nibble = (x_>>4); c=nib2str(nibble);
|
|
59
|
+
nibble = (x_&0x000f);
|
|
60
|
+
d = nib2str(x_);
|
|
61
|
+
|
|
62
|
+
a_ = (a!=='0');
|
|
63
|
+
b_ = (b!=='0');
|
|
64
|
+
c_ = (c!=='0');
|
|
65
|
+
d_ = (d!=='0');
|
|
66
|
+
|
|
67
|
+
if (littleendian) {
|
|
68
|
+
if (!a_ && !b_ && !c_)
|
|
69
|
+
return d;
|
|
70
|
+
else if (!a_ && !b_)
|
|
71
|
+
return (c+d);
|
|
72
|
+
else if (!a_)
|
|
73
|
+
return (b+c+d);
|
|
74
|
+
else
|
|
75
|
+
return (a+b+c+d);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
if (!d_ && !c_ && !b_)
|
|
79
|
+
return (a);
|
|
80
|
+
else if (!d_ && !c_)
|
|
81
|
+
return (b+a);
|
|
82
|
+
else if (!d_)
|
|
83
|
+
return (c+b+a);
|
|
84
|
+
else
|
|
85
|
+
return (d+c+b+a);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
parse = (x:string): Block => {
|
|
90
|
+
let rs:RegExp[];
|
|
91
|
+
let rs_:boolean[];
|
|
92
|
+
let x_:string;
|
|
93
|
+
let ret:boolean;
|
|
94
|
+
let arr:BlockData;
|
|
95
|
+
let block:Block;
|
|
96
|
+
let split:string[];
|
|
97
|
+
let cidr:number;
|
|
98
|
+
let scidr:string;
|
|
99
|
+
let forward:boolean;
|
|
100
|
+
let idx:number;
|
|
101
|
+
let field_:number;
|
|
102
|
+
let idx_:number;
|
|
103
|
+
let next:()=>number;
|
|
104
|
+
|
|
105
|
+
next = (): number => {
|
|
106
|
+
let field:number;
|
|
107
|
+
let sfield:string;
|
|
108
|
+
|
|
109
|
+
if (idx === 255)
|
|
110
|
+
throw 1;
|
|
111
|
+
|
|
112
|
+
if ((idx < 0) || (idx > 15))
|
|
113
|
+
idx = 255;
|
|
114
|
+
|
|
115
|
+
sfield = split[idx]
|
|
116
|
+
|| '';
|
|
117
|
+
|
|
118
|
+
if (forward)
|
|
119
|
+
idx++;
|
|
120
|
+
else
|
|
121
|
+
idx--;
|
|
122
|
+
|
|
123
|
+
if (sfield === '')
|
|
124
|
+
throw 2;
|
|
125
|
+
else
|
|
126
|
+
field = parseInt('0x'+sfield);
|
|
127
|
+
|
|
128
|
+
return field;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// peek = (): number => {
|
|
132
|
+
// let field:number;
|
|
133
|
+
// let sfield:string;
|
|
134
|
+
// let idx_:number;
|
|
135
|
+
|
|
136
|
+
// if (forward && (idx === 15))
|
|
137
|
+
// throw 1;
|
|
138
|
+
// else if (!forward && (!idx))
|
|
139
|
+
// throw 1;
|
|
140
|
+
|
|
141
|
+
// idx_ = (forward) ?
|
|
142
|
+
// (idx+1) :
|
|
143
|
+
// (idx-1);
|
|
144
|
+
|
|
145
|
+
// sfield = split[idx_]
|
|
146
|
+
// || '';
|
|
147
|
+
|
|
148
|
+
// if (sfield === '')
|
|
149
|
+
// throw 2;
|
|
150
|
+
// else
|
|
151
|
+
// field = parseInt('0x'+sfield);
|
|
152
|
+
|
|
153
|
+
// return field;
|
|
154
|
+
// }
|
|
155
|
+
|
|
156
|
+
x_ = x
|
|
157
|
+
.toLowerCase();
|
|
158
|
+
|
|
159
|
+
rs = [
|
|
160
|
+
/^([0-9a-f]{1,4}[:]?){16}\/[0-9]{1,3}$/,
|
|
161
|
+
/^([0-9a-f]{1,4}[:])*[:]([0-9a-f]{1,4}[:]?)*$/,
|
|
162
|
+
/^([0-9a-f]{1,4}[:])*[:]([0-9a-f]{1,4}[:]?)*\/[0-9]{1,3}$/
|
|
163
|
+
];
|
|
164
|
+
rs_ = rs
|
|
165
|
+
.map((r:RegExp): boolean => r.test(x_));
|
|
166
|
+
|
|
167
|
+
ret = rs_.some((b:boolean): boolean => !!b);
|
|
168
|
+
if (!ret)
|
|
169
|
+
return null as never;
|
|
170
|
+
|
|
171
|
+
forward = true;
|
|
172
|
+
idx = 0;
|
|
173
|
+
cidr = 257;
|
|
174
|
+
arr = new Uint16Array(16);
|
|
175
|
+
split = (x_
|
|
176
|
+
.split('/')[0]||x_)
|
|
177
|
+
.split(':');
|
|
178
|
+
|
|
179
|
+
switch (true) {
|
|
180
|
+
case rs_[1]:
|
|
181
|
+
case rs_[2]:
|
|
182
|
+
scidr = x_
|
|
183
|
+
.split('/')[1]
|
|
184
|
+
|| '257';
|
|
185
|
+
cidr = parseInt(scidr);
|
|
186
|
+
if (cidr === 257)
|
|
187
|
+
return null as never;
|
|
188
|
+
|
|
189
|
+
idx_ = idx;
|
|
190
|
+
while (true) {
|
|
191
|
+
field_ = 0;
|
|
192
|
+
try {
|
|
193
|
+
field_ = next();
|
|
194
|
+
} catch(errno) {
|
|
195
|
+
if (errno === 1)
|
|
196
|
+
break;
|
|
197
|
+
else if (errno === 2) {
|
|
198
|
+
if (!forward)
|
|
199
|
+
break;
|
|
200
|
+
else {
|
|
201
|
+
forward = false;
|
|
202
|
+
idx = (split.length-1);
|
|
203
|
+
idx_ = 15;
|
|
204
|
+
|
|
205
|
+
continue;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
arr[idx_] = field_;
|
|
210
|
+
idx_ = (forward) ?
|
|
211
|
+
++idx_ :
|
|
212
|
+
--idx_;
|
|
213
|
+
}
|
|
214
|
+
break;
|
|
215
|
+
|
|
216
|
+
case rs_[0]:
|
|
217
|
+
scidr = x_
|
|
218
|
+
.split('/')[1]
|
|
219
|
+
|| '256';
|
|
220
|
+
cidr = parseInt(scidr);
|
|
221
|
+
|
|
222
|
+
do {
|
|
223
|
+
field_ = 0;
|
|
224
|
+
idx_ = idx;
|
|
225
|
+
try {
|
|
226
|
+
field_ = next();
|
|
227
|
+
} catch(errno) {
|
|
228
|
+
if (errno === 1)
|
|
229
|
+
break;
|
|
230
|
+
else if (errno === 2)
|
|
231
|
+
return null as never;
|
|
232
|
+
}
|
|
233
|
+
arr[idx_] = field_;
|
|
234
|
+
} while (idx_<15);
|
|
235
|
+
break;
|
|
236
|
+
|
|
237
|
+
default:
|
|
238
|
+
return null as never;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
return {data: arr, cidr};
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
bestidx = (block:Block): number => {
|
|
245
|
+
type candidate = {idx:number,amount:number};
|
|
246
|
+
let idx:number;
|
|
247
|
+
let cur:candidate;
|
|
248
|
+
let cs:candidate[];
|
|
249
|
+
let counting:boolean;
|
|
250
|
+
|
|
251
|
+
idx = 0;
|
|
252
|
+
cur = {idx,amount:0};
|
|
253
|
+
cs = [];
|
|
254
|
+
counting = false;
|
|
255
|
+
|
|
256
|
+
block.data.forEach((x:number):void => {
|
|
257
|
+
if (!idx) {
|
|
258
|
+
idx++;
|
|
259
|
+
return void 0;
|
|
260
|
+
}
|
|
261
|
+
else if (idx===15)
|
|
262
|
+
if (counting) {
|
|
263
|
+
counting = false;
|
|
264
|
+
|
|
265
|
+
if (!x)
|
|
266
|
+
cur.amount++;
|
|
267
|
+
cs.push(cur);
|
|
268
|
+
cur = {idx:0,amount:0};
|
|
269
|
+
|
|
270
|
+
return void 0;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
if (!x)
|
|
274
|
+
if (!counting) {
|
|
275
|
+
counting = true;
|
|
276
|
+
cur = {idx,amount:1};
|
|
277
|
+
}
|
|
278
|
+
else
|
|
279
|
+
cur.amount++;
|
|
280
|
+
else
|
|
281
|
+
if (counting) {
|
|
282
|
+
counting = false;
|
|
283
|
+
cs.push(cur);
|
|
284
|
+
cur = {idx:0,amount:0};
|
|
285
|
+
}
|
|
286
|
+
idx++;
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
if (!cs.length)
|
|
290
|
+
return 0;
|
|
291
|
+
|
|
292
|
+
cs = cs
|
|
293
|
+
.sort((a:candidate,b:candidate): number => (a.amount<b.amount) ?
|
|
294
|
+
1 :
|
|
295
|
+
(a.amount>b.amount) ?
|
|
296
|
+
-1 :
|
|
297
|
+
0
|
|
298
|
+
);
|
|
299
|
+
cur = cs.shift()
|
|
300
|
+
|| {idx:0,amount:0};
|
|
301
|
+
|
|
302
|
+
return cur.idx;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
tostr = (block:Block): string => {
|
|
306
|
+
let counting:boolean;
|
|
307
|
+
let best:number;
|
|
308
|
+
let arr:string[];
|
|
309
|
+
let str:string;
|
|
310
|
+
|
|
311
|
+
counting = false;
|
|
312
|
+
arr = [];
|
|
313
|
+
best = bestidx(block);
|
|
314
|
+
block.data
|
|
315
|
+
.forEach((x:number,idx:number): void =>{
|
|
316
|
+
if (counting)
|
|
317
|
+
if (!x)
|
|
318
|
+
return void 0;
|
|
319
|
+
else
|
|
320
|
+
counting = false;
|
|
321
|
+
else
|
|
322
|
+
if (idx && (idx===best)) {
|
|
323
|
+
counting = true;
|
|
324
|
+
arr.push('');
|
|
325
|
+
|
|
326
|
+
return void 0;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
arr.push(hex16(x));
|
|
330
|
+
});
|
|
331
|
+
|
|
332
|
+
return arr.join(':')
|
|
333
|
+
.concat('/'+block.cidr.toString());
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export { mkblock,tostr };
|
|
337
|
+
export type { Block };
|
package/index.ts
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/* index.ts */
|
|
2
|
+
import { mkblock, tostr } from './blocks.js';
|
|
3
|
+
import type { Block } from './blocks.js';
|
|
4
|
+
|
|
5
|
+
let block:Block;
|
|
6
|
+
let str:string;
|
|
7
|
+
let str_:string;
|
|
8
|
+
let idx:number;
|
|
9
|
+
let log:(...args:any[])=>void;
|
|
10
|
+
let fail:(...args:any[])=>never;
|
|
11
|
+
|
|
12
|
+
log = console.log;
|
|
13
|
+
fail = (...args:any[]): never => {
|
|
14
|
+
console.error(...args);
|
|
15
|
+
throw new Error();
|
|
16
|
+
|
|
17
|
+
return void 0 as never;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
block = mkblock(str='fe80::20c:29ff:fe9f:807c/64');
|
|
21
|
+
str_ = tostr(block);
|
|
22
|
+
log(str, block, str_);
|
|
23
|
+
|
|
24
|
+
block = mkblock(str='fe80:0000:0000:000a:0000:0000:0000:'
|
|
25
|
+
+'0000:0000:0000:0000:0000:020c:29ff:fe9f:807c/128');
|
|
26
|
+
str_ = tostr(block);
|
|
27
|
+
log(str, block, str_);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fagelsjo/blocks",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.2",
|
|
5
5
|
"description": "Handle blocks of bigints in an IPv6 kind of way.",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"scripts": {
|
|
@@ -16,6 +16,10 @@
|
|
|
16
16
|
],
|
|
17
17
|
"author": "@dr-Jonas-Birch",
|
|
18
18
|
"license": "MIT",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@types/node": "^25.2.3",
|
|
21
|
+
"@types/typescript": "^2.0.0"
|
|
22
|
+
},
|
|
19
23
|
"devDependencies": {
|
|
20
24
|
"@types/node": "^25.2.3",
|
|
21
25
|
"@types/typescript": "^2.0.0",
|
package/tsconfig.json
CHANGED