2

UUIDv4 を URL に適した文字列にフォーマットしようとしています。base16 の一般的な形式はかなり長く、ダッシュが含まれています。

xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx

ダッシュとアンダースコアを避けるために、base58 (ビットコインのように) を使用するつもりだったので、各文字は完全にエンコードされsqrt(58).floor = 7 bitsます。

次のようにしてuuidをバイナリにパックできます。

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

8 ビットの符号なし整数を取得するには、次のようにします。

binary.unpack('C*')

すべての 7 ビットを 8 ビットの符号なし整数にアンパックするにはどうすればよいですか? 一度に 7 ビットをスキャンし、上位ビットを 0 に設定するパターンはありますか?

4

2 に答える 2

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

そしてまた戻る

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

テンプレートから uuid 形式を再構築するための便利なパターン

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"      
于 2015-11-24T22:08:31.933 に答える
1

John La Rooy の答えは素晴らしいですが、Base58 アルゴリズムがいかに単純であるかを指摘したかっただけです。(base58 gem に大まかに基づいており、オリジナルのボーナスint_to_uuid機能が追加されています):

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
于 2015-11-25T06:59:04.613 に答える