Skip to content

Instantly share code, notes, and snippets.

@RyanHirsch
Last active February 4, 2021 17:59
Show Gist options
  • Save RyanHirsch/1cbfba45119fd806787d05b9b97186c6 to your computer and use it in GitHub Desktop.
Save RyanHirsch/1cbfba45119fd806787d05b9b97186c6 to your computer and use it in GitHub Desktop.
code to convert uuid to b58 strings
const uuid1 = "da507fb6-5417-495a-b1f3-a23518f6b9ea";
const uuid2 = "b21e5078-8da2-421b-8b26-ace980f4164a";
//#region Uint8Array
/* https://stackoverflow.com/questions/38987784/how-to-convert-a-hexadecimal-string-to-uint8array-and-back-in-javascript */
const fromHexString = hexString =>
new Uint8Array(hexString.match(/.{1,2}/g).map(byte => parseInt(byte, 16)));
const toHexString = bytes =>
bytes.reduce((str, byte) => str + byte.toString(16).padStart(2, '0'), '');
//#endregion
//#region base58
/* https://gist.github.com/diafygi/90a3e80ca1c2793220e5/ */
var to_b58 = function(
B, //Uint8Array raw byte input
A="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" //Base58 characters (i.e. "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
) {
var d = [], //the array for storing the stream of base58 digits
s = "", //the result string variable that will be returned
i, //the iterator variable for the byte input
j, //the iterator variable for the base58 digit array (d)
c, //the carry amount variable that is used to overflow from the current base58 digit to the next base58 digit
n; //a temporary placeholder variable for the current base58 digit
for(i in B) { //loop through each byte in the input stream
j = 0, //reset the base58 digit iterator
c = B[i]; //set the initial carry amount equal to the current byte amount
s += c || s.length ^ i ? "" : 1; //prepend the result string with a "1" (0 in base58) if the byte stream is zero and non-zero bytes haven't been seen yet (to ensure correct decode length)
while(j in d || c) { //start looping through the digits until there are no more digits and no carry amount
n = d[j]; //set the placeholder for the current base58 digit
n = n ? n * 256 + c : c; //shift the current base58 one byte and add the carry amount (or just add the carry amount if this is a new digit)
c = n / 58 | 0; //find the new carry amount (floored integer of current digit divided by 58)
d[j] = n % 58; //reset the current base58 digit to the remainder (the carry amount will pass on the overflow)
j++ //iterate to the next base58 digit
}
}
while(j--) //since the base58 digits are backwards, loop through them in reverse order
s += A[d[j]]; //lookup the character associated with each base58 digit
return s //return the final base58 string
}
var from_b58 = function(
S, //Base58 encoded string input
A="123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" //Base58 characters (i.e. "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz")
) {
var d = [], //the array for storing the stream of decoded bytes
b = [], //the result byte array that will be returned
i, //the iterator variable for the base58 string
j, //the iterator variable for the byte array (d)
c, //the carry amount variable that is used to overflow from the current byte to the next byte
n; //a temporary placeholder variable for the current byte
for(i in S) { //loop through each base58 character in the input string
j = 0, //reset the byte iterator
c = A.indexOf( S[i] ); //set the initial carry amount equal to the current base58 digit
if(c < 0) //see if the base58 digit lookup is invalid (-1)
return undefined; //if invalid base58 digit, bail out and return undefined
c || b.length ^ i ? i : b.push(0); //prepend the result array with a zero if the base58 digit is zero and non-zero characters haven't been seen yet (to ensure correct decode length)
while(j in d || c) { //start looping through the bytes until there are no more bytes and no carry amount
n = d[j]; //set the placeholder for the current byte
n = n ? n * 58 + c : c; //shift the current byte 58 units and add the carry amount (or just add the carry amount if this is a new byte)
c = n >> 8; //find the new carry amount (1-byte shift of current byte value)
d[j] = n % 256; //reset the current byte to the remainder (the carry amount will pass on the overflow)
j++ //iterate to the next byte
}
}
while(j--) //since the byte array is backwards, loop through it in reverse order
b.push( d[j] ); //append each byte to the result
return new Uint8Array(b) //return the final byte array in Uint8Array format
}
//#endregion
//#region uuid-conversions
const uuidToHex = (uuid:string) => uuid.replace(/-/g,"");
const hexToUuid = (hex:string) => `${hex.substr(0,8)}-${hex.substr(8,4)}-${hex.substr(12,4)}-${hex.substr(16,4)}-${hex.substr(20)}`;
//#endregion
const uuidToB58 = (uuid:string) => to_b58(fromHexString(uuidToHex(uuid)))
const b58ToUuid = (b58:string) => hexToUuid(toHexString(from_b58(b58)))
const verifyRoundTrip = (uuid:string) => b58ToUuid(uuidToB58(uuid)) === uuid
console.log(uuidToHex(uuid1));
console.log(hexToUuid(uuidToHex(uuid1)))
console.log(uuidToB58(uuid1))
console.log(verifyRoundTrip(uuid1))
console.log(verifyRoundTrip(uuid2))
uuidToB58(uuid1).length
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment