rubybinaryuuidbase58

How to unpack 7-bits at a time in ruby?


I'm trying to format a UUIDv4 into a url friendly string. The typical format in base16 is pretty long and has dashes:

xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx

To avoid dashes and underscores I was going to use base58 (like bitcoin does) so each character fully encode sqrt(58).floor = 7 bits.

I can pack the uuid into binary with:

[ uuid.delete('-') ].pack('H*')

To get 8-bit unsigned integers its:

binary.unpack('C*')

How can i unpack every 7-bits into 8-bit unsigned integers? Is there a pattern to scan 7-bits at a time and set the high bit to 0?


Solution

  • require 'base58'
    uuid ="123e4567-e89b-12d3-a456-426655440000"
    Base58.encode(uuid.delete('-').to_i(16))
    => "3fEgj34VWmVufdDD1fE1Su"
    

    and back again

    Base58.decode("3fEgj34VWmVufdDD1fE1Su").to_s(16)
     => "123e4567e89b12d3a456426655440000"
    

    A handy pattern to reconstruct the uuid format from a template

    template = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'
    src = "123e4567e89b12d3a456426655440000".each_char
    template.each_char.reduce(''){|acc, e| acc += e=='-' ? e : src.next}  
     => "123e4567-e89b-12d3-a456-426655440000"