Skip to content

Instantly share code, notes, and snippets.

@joalbertg
Last active May 20, 2022 19:00
Show Gist options
  • Save joalbertg/fd5a49c72b28fa8f4f3f49b6844ed26b to your computer and use it in GitHub Desktop.
Save joalbertg/fd5a49c72b28fa8f4f3f49b6844ed26b to your computer and use it in GitHub Desktop.
Friendlier UUID
# frozen_string_literal: true
class FriendlierUuid
def initialize(uuid)
@uuid = uuid
end
def encode
remove_hyphens
conver_hexadecimal_to_bcd
add_prepend_zeros
group_binary_digits
convert_to_encoding_alphabet
retrieve_alphabet_characters
end
def decoded
uuid_dup ||= encode
@uuid_decoded = uuid_dup
conver_to_base10_values
convert_to_6bits_binaries
group_binary_digits(encoding: false)
remove_prepend_zeros
conver_bcd_to_hexadecimal
add_hyphens
end
def self.base16
(0..15).map(&pro_base(HEXADECIMAL_SYSTEM))
end
def self.base16_to_base2
(0..15).map(&pro_base(BINARY_SYSTEM))
end
# each hexadecimal digit requires up to 4 bits
# 15.to_s(2) => '1111', values in BCD
def self.show_base16_to_base2_with_4bits
base16_to_base2.map { |binary| binary.rjust(4, '0') }
end
private
attr_reader :uuid, :uuid_dup, :uuid_decoded
BINARY_SYSTEM = 2
HEXADECIMAL_SYSTEM = 16
# index 0 - 63
# each character in a 64 character set would need 6 bits
# 63.to_s(2) => '111111'
ALPHABET = %w[
0 1 2 3 4 5 6 7 8 9
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
- _
].freeze
# returns 32 digits
def remove_hyphens
@uuid_dup = uuid.split('-').join
end
# binary-coded decimal
def conver_hexadecimal_to_bcd
binary_characters = uuid_dup.chars.map { |char| char.hex.to_s(BINARY_SYSTEM).rjust(4, '0') }
@uuid_dup = binary_characters.join
end
# To represent a number between 0 and 63 we need 6 binary digits.
# If you take 128 and you divide it by 6 you will notice that we get 21.3.
# If only we had 132 binary digits, then we would have been able to group
# them into exactly 22 groups. Add a couple of zeros to the front (left) of the number.
def add_prepend_zeros
@uuid_dup = uuid_dup.prepend('0000')
end
def convert_to_encoding_alphabet
@uuid_dup = uuid_dup.map { |binary| binary.to_i(BINARY_SYSTEM) }
end
def retrieve_alphabet_characters
characters = uuid_dup.map { |index_number| ALPHABET[index_number] }
@uuid_dup = characters.join
end
def split_string
uuid_decoded.split('')
end
def conver_to_base10_values
@uuid_decoded = split_string.map { |char| ALPHABET.index(char) }
end
def convert_to_6bits_binaries
binaries = uuid_decoded.map { |number| number.to_s(BINARY_SYSTEM).rjust(6, '0') }
@uuid_decoded = binaries.join
end
def group_binary_digits(encoding: true)
@uuid_dup = uuid_dup.scan(/.{6}/) if encoding
@uuid_decoded = uuid_decoded.scan(/.{4}/) unless encoding
end
def remove_prepend_zeros
uuid_decoded.shift
end
def conver_bcd_to_hexadecimal
hexadecimals = uuid_decoded.map { |binary| binary.to_i(BINARY_SYSTEM).to_s(HEXADECIMAL_SYSTEM) }
@uuid_decoded = hexadecimals.join
end
def add_hyphens
unpack = uuid_decoded.unpack('a8a4a4a4a12')
@uuid_decoded = unpack.join('-')
end
def self.pro_base(base)
proc { |decimal_number| decimal_number.to_s(base) }
end
private_class_method :pro_base
end
# frozen_string_literal: true
# Quickstart
#
# ruby main.rb
require 'SecureRandom'
require_relative 'friendlier_uuid'
uuid_origin = SecureRandom.uuid
friendlier_uuid = FriendlierUuid.new(uuid_origin)
puts "UUID: #{uuid_origin}"
puts "encode: #{friendlier_uuid.encode}"
puts "decoded: #{friendlier_uuid.decoded}"
UUID: 143339e6-307a-4266-bad8-f3506a7cc8a0
encode: 0KCpdcC7f2PhhOyr1gVCYW
decode: 143339e6-307a-4266-bad8-f3506a7cc8a0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment