Skip to content

Instantly share code, notes, and snippets.

@jrunning
Last active November 17, 2020 03:55
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jrunning/62cf199822a25ce441d1 to your computer and use it in GitHub Desktop.
Save jrunning/62cf199822a25ce441d1 to your computer and use it in GitHub Desktop.
UUID to Base 58 in Ruby
# base58_to_int and int_to_base58 loosely based on base58 gem by Douglas F. Shearer
# https://github.com/dougal/base58
ALPHABET = "123456789abcdefghijkmnopqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ".chars
BASE = ALPHABET.size
def base58_to_int(base58_val)
base58_val.chars
.reverse_each.with_index
.reduce(0) do |int_val, (char, index)|
int_val + ALPHABET.index(char) * BASE ** index
end
end
def int_to_base58(int_val)
''.tap do |base58_val|
while int_val > 0
int_val, mod = int_val.divmod(BASE)
base58_val.prepend ALPHABET[mod]
end
end
end
def int_to_uuid(int_val)
base16_val = int_val.to_s(16)
[ 8, 4, 4, 4, 12 ].map do |n|
base16_val.slice!(0...n)
end.join('-')
end
uuid = "123e4567-e89b-12d3-a456-426655440000"
int_val = uuid.delete('-').to_i(16)
base58_val = int_to_base58(int_val)
int_val2 = base58_to_int(base58_val)
uuid2 = int_to_uuid(int_val2)
printf <<END, uuid, int_val, base_58_val, int_val2, uuid2
Input UUID: %s
Input UUID as integer: %d
Integer encoded as base 58: %s
Integer decoded from base 58: %d
Decoded integer as UUID: %s
END
Input UUID: 123e4567-e89b-12d3-a456-426655440000
Input UUID as integer: 24249434048109030647017182302883282944
Integer encoded as base 58: 3fEgj34VWmVufdDD1fE1Su
Integer decoded from base 58: 24249434048109030647017182302883282944
Decoded integer as UUID: 123e4567-e89b-12d3-a456-426655440000
@patrotom
Copy link

patrotom commented May 12, 2020

Looks good, but the problem here is a situation when the UUID string starts with a number of zeros. These zeros are lost during the encoding process, and the decoded string is different than the original one. I suggest to add 32 - base16_val.size leading zeros to the base16_val if base16_val.size < 32. The edge case here is, for example, null UUID: 00000000-0000-0000-0000-000000000000.

Add this after the line 25:

base16_val = "0" * (32 - base16_val.size) + base16_val

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment