2017-12-15 8 views
2

この質問は私の前の質問に従います:How can I convert a UUID to a string using a custom character set in Ruby? しかし、私はそれを別の具体的な質問として定式化しようとします。ruby​​ base64最後に余白ができないように2ビット文字で始まる128ビットの数字を符号化します

私は進値としてRubyの128ビットのUUIDを持っています:私が正しくIFC仕様(http://www.buildingsmart-tech.org/ifc/IFC2x3/TC1/html/ifcutilityresource/lexical/ifcgloballyuniqueid.htm)を取得する場合

SecureRandom.uuid #=> "2d931510-d99f-494a-8c67-87feb05e1594" 

、私はBase64でしたいが、これを符号化するが、代わりに最後にパディングを取得します出力を6ビット(64オプションに必要)ではなく、2ビット文字(4オプション)で開始したい。

このようにして、私は22文字の文字列(2ビットのうち1ビット、合計で128ビットの6ビットの21ビット)で終わることができると思います。

このようにRubyのbase64を微調整することはできますか?

答えて

2

短答:いいえ。技術的に言えば、それは標準のBase64ではないので、Rubyの標準ライブラリはそれを扱わないでしょう。

RubyのBase64 libはその入力をバイト単位で受け取りますので、入力データを8で割り切れるようにする必要があります。ただし、UUIDの前に4のゼロビットが必要なので、4 + 128 = 132となり、 8の倍数は136すなわち17バイトである。あなたは、最後に余分なランダム性を捨てることができます。

x = SecureRandom.gen_random 17 # get a little extra randomness 
x[0] = (x[0].ord & 0x0f).chr  # 0 out the first four bits 
Base64.strict_encode64(x)[0...22] # discard extra randomness 

このアプローチの一つの欠点は、あなたの128ビットのUUIDが変なふうに自分自身で見ることxとハードの内側に整列されていることです。

[x.unpack("B*")[0][4...132]].pack("B*") 
+0

正しい結果を得るためには6ビットのセットが必要だと思うので、base64だけが入力としてバイトを取る場合は、おそらく私の質問自体は間違っています。 (6つのオプションは64個のオプションに必要です)それは可能でしょうか?そうすると、「いいえ」が正解になり、私はこれらのビットを別の方法で見つける必要があります。私が提供したリンクでは、「C」コード例もありますが、読みにくいです。 –

+0

@JanBrouwerあなたの推論は正しい、実際には。問題は、一方では、あなたが記述したとおりに正確に動作する数値表現である "base 64"があり、標準化されたバイトベースのエンコーディングスキームである "base 64 _encoding_"があるということです。 128バイナリ桁を22桁64桁にすることは完全に有効です。しかし、それは_standard_ではないので、Rubyはstdlibでそれを処理しません。 – Max

関連する問題