]> code.delx.au - monosys/blob - bin/hexhost
notes: fix raspi install notes, also @home -> @username
[monosys] / bin / hexhost
1 #!/usr/bin/env node
2
3 'use strict';
4
5 const BLOCKSIZE = 3;
6 const CHARS1 = [
7 ' ',
8 ...'0123456789'.split(''),
9 ...'abcdefghijklmnopqrstuvwxyz'.split(''),
10 '_',
11 '-',
12 ];
13 const SHIFT = BigInt(Math.ceil(Math.log2(CHARS1.length ** BLOCKSIZE)));
14 const MASK = 2n**SHIFT - 1n;
15
16 const CHARSN = [...Array(BLOCKSIZE - 1)].reduce((acc) => acc.map((v1) => CHARS1.map((v2) => ''+v1+v2)).flat(), CHARS1);
17 const FMAP = new Map(CHARSN.map((v, i) => [''+v, BigInt(i)]));
18 const RMAP = new Map(CHARSN.map((v, i) => [BigInt(i), ''+v]));
19
20 function main(arg1, arg2) {
21 if (!arg1) {
22 console.error('Usage: hexhost fdxx::4a59954e');
23 console.error('Usage: hexhost fdxx:: hostname');
24 process.exit(1);
25 }
26
27 if (arg2) {
28 const prefix = arg1;
29 const suffix = encode(arg2).replaceAll(/(.{4})/g, '$1:').replace(/:$/, '');
30 console.log(prefix + suffix);
31 } else {
32 const [, suffix] = arg1.split(/::|:0:/);
33 console.log(decode(suffix));
34 }
35 }
36
37 function decode(input) {
38 input = input && input.replaceAll(':', '');
39 if (!input) {
40 throw new Error('No suffix found');
41 }
42 input = BigInt('0x' + input);
43 let output = [];
44 while (input > 0) {
45 const encodedBlock = input & MASK;
46 input >>= SHIFT;
47 const block = RMAP.get(encodedBlock);
48 if (block !== undefined) {
49 output.push(block);
50 }
51 }
52 return output.reverse().join('').trim();
53 }
54
55 function encode(input) {
56 if (input.length / BLOCKSIZE > (64n / SHIFT)) {
57 throw new Error('Input is too long to fit in a /64!');
58 }
59
60 input = input.toLowerCase();
61
62 let out = BigInt(0);
63 for (let i = 0; i < input.length; i += BLOCKSIZE) {
64 const block = input.substring(i, i + BLOCKSIZE).padEnd(BLOCKSIZE);
65 const encodedBlock = FMAP.get(block);
66 if (encodedBlock !== undefined) {
67 out = (out << SHIFT) + encodedBlock;
68 }
69 }
70 return out.toString(16);
71 }
72
73 main(process.argv[2], process.argv[3]);