Created
February 3, 2024 16:04
-
-
Save intech/4071f83573d00a2ac47ac04c7e32ddc5 to your computer and use it in GitHub Desktop.
UUIDv5 serialization and deserialization
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Code compression - compresses given [A-Za-z0-9]+ string to hex, and/or to | |
* UUIDv5, and decopresses it back. | |
* Used by Rehau piece code compression, to generate unique product UUID based | |
* on code value. | |
* Can't use ordinary hex, as "16-bytes string".toString("hex") would result in | |
* 32 symbol hex string, which is too long to be encoded into UUID. | |
*/ | |
const char0 = '0'.charCodeAt(0); | |
const char9 = '9'.charCodeAt(0); | |
const num_range = char9 - char0 + 1; | |
const chara = 'a'.charCodeAt(0); | |
const charz = 'z'.charCodeAt(0); | |
const let_range = charz - chara + 1; | |
const charA = 'A'.charCodeAt(0); | |
const charZ = 'Z'.charCodeAt(0); | |
const up_let_range = charZ - charA + 1; | |
const sym_to_int = (sym) => { | |
let c = 0; | |
const s = sym.charCodeAt(0); | |
if(s >= char0 && s <= char9) { | |
c = s - char0; | |
} else if(s >= charA && s <= charZ) { | |
c = s - charA + num_range; | |
} else if(s >= chara && s <= charz) { | |
c = s - chara + num_range + up_let_range; | |
} else { | |
c = -1; | |
} | |
return c; | |
}; | |
const decompress_sym = (c) => { | |
let s = -1; | |
if(c < num_range) { | |
s = char0 + c; | |
} else if(c < (num_range + up_let_range)) { | |
s = charA + c - num_range; | |
} else if(c < (num_range + up_let_range + let_range)) { | |
s = chara + c - num_range - up_let_range; | |
} | |
return String.fromCharCode(s); | |
}; | |
const compress_ints = (ints, bits_per_int) => { | |
const buffer = Buffer.alloc(bits_per_int * ints.length / 8); | |
for(let i = 0; i < ints.length; ++i) { | |
const n = ints[i]; | |
for(let b = 0; b < bits_per_int; ++b) { | |
const bv = n & (1 << b); | |
if(bv) { | |
const byteidx = Math.floor((i * bits_per_int + b) / 8); | |
const bit = (i * bits_per_int + b) % 8; | |
buffer[byteidx] |= (1 << bit); | |
} | |
} | |
} | |
return buffer; | |
} | |
const decompress_buffer = (buffer, bits_per_int) => { | |
const ints = []; | |
const num_ints = Math.floor(buffer.length * 8 / bits_per_int); | |
for(let i = 0; i < num_ints; ++i) { | |
let num = 0; | |
for(let b = 0; b < bits_per_int; ++b) { | |
const byteidx = Math.floor((i * bits_per_int + b) / 8); | |
const bit = (i * bits_per_int + b) % 8; | |
const bv = buffer[byteidx] & (1 << bit); | |
if(bv) { | |
num |= 1 << b; | |
} | |
} | |
ints.push(num); | |
} | |
return ints; | |
}; | |
const to_uuid_str = (version, val) => { | |
val = val + "000000"; | |
return val.substr(0,8) + '-' + | |
val.substr(8,4) + '-' + | |
(version + val.substr(12,3)) + '-' + | |
'8' + val.substr(15,3) + '-' + | |
val.substr(18,12); | |
} | |
const from_uuid_str = (u) => { | |
return u.substr(0, 8) + | |
u.substr(9, 4) + | |
u.substr(15, 3) + | |
u.substr(20, 3) + | |
u.substr(24, 6); | |
}; | |
export const compressToHex = (code) => { | |
const syms = code.split('').map((c) => sym_to_int(c)); | |
const buffer = compress_ints(syms, 6); | |
return buffer.toString("hex"); | |
}; | |
export const compressToUUID = (code) => { | |
return to_uuid_str(5, compressToHex(code)); | |
}; | |
export const decompressFromHex = (hex) => { | |
const compressed_buffer = Buffer.from(hex, "hex"); | |
const decompressed_ints = decompress_buffer(compressed_buffer, 6); | |
const decompressed = decompressed_ints.map((d) => decompress_sym(d)); | |
return decompressed.join(''); | |
}; | |
export const decompressFromUUID = (uuid) => { | |
if(uuid.substr(30) !== "000000") return undefined; | |
return decompressFromHex(from_uuid_str(uuid)); | |
}; | |
export const hexToUUID = (hex) => { | |
return to_uuid_str(5, hex); | |
}; | |
export const hexFromUUID = (uuid) => { | |
return from_uuid_str(uuid); | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment