Skip to content

Instantly share code, notes, and snippets.

@nahidakbar
Created September 14, 2019 05:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nahidakbar/40f65ca6abe1f4606c2f64acf8887f0d to your computer and use it in GitHub Desktop.
Save nahidakbar/40f65ca6abe1f4606c2f64acf8887f0d to your computer and use it in GitHub Desktop.
Encode and decode numbers into codes
const [ns, s] = process.hrtime();
const nsTime = (s * 1e6 + ns);
function encode(num, digits = 15, off = 0) {
const rand = off ? Math.random().toString(26).substring(1, 1 + off) : '';
const str = (num.toString(26) + rand).split('');
let input = str.map(ch => ch === '.' ? '-' : (parseInt(ch, 26) + 10).toString(36)).join('').toUpperCase();
input = input.split('')
input.unshift('{');
input.push('}');
const table = [];
for (let x = 0; x < input.length; x++) {
table.push(input.slice())
input.push(input.shift());
}
table.sort();
const encoded = table.map(row => row[row.length - 1]);
const reconstructed = [];
for (let x = 0, y; x < encoded.length;) {
const ch = encoded[x];
for (y = x; encoded[y] === ch; y++) {
}
const count = y - x;
if (count === 1) {
if (ch === '{') {
reconstructed.push('0');
} else if (ch === '}') {
reconstructed.push('1');
} else {
reconstructed.push(ch);
}
} else {
let left = count;
while (left > 0) {
if (left > 9) {
reconstructed.push(ch + 9);
left -= 9;
} else if (left === 1) {
reconstructed.push(ch);
left -= 1;
} else {
reconstructed.push(ch + left);
left = 0;
}
}
}
x += count;
}
const output = reconstructed.join('');
if (output.length < digits) {
return encode(num, digits, off + 1);
}
return output;
}
function decode(encoded) {
const input = [];
encoded = encoded.split('')
.forEach((ch, i, inp) => {
if (ch.match(/^[A-Z-]+/)) {
input.push(ch);
} else if (ch === '0') {
input.push('{');
} else if (ch === '1') {
input.push('}');
} else {
let count = parseInt(ch);
while (count-- > 1) {
input.push(inp[i - 1]);
}
}
});
const table = [];
for (let x = 0; x < input.length; x++) {
table.push('');
}
while (table[0].length < input.length) {
for (let x = 0; x < input.length; x++) {
table[x] = input[x] + table[x];
}
table.sort();
}
let match = table.find(x => x.match(/^[{][^}]+[}]$/));
match = match.substring(1, match.length - 1);
match = parseInt(match.split('').map(ch => ch === '-' ? '.' : (parseInt(ch, 36) - 10).toString(26)).join(''), 26);
return match;
}
for (let x = 1; x < 1e20; x *= 2) {
console.log(x, encode(x), decode(encode(x)));
}
console.log(nsTime, encode(nsTime), decode(encode(nsTime)));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment