2

任意の長さのバイナリ文字列の数値表現が必要です。この一見些細な作業は、予想外に複雑であることが判明しました。これまでのところ私が思いつくことができる最高のものは

string.unpack('H*')[0].to_i(16)

ただし、この操作には可逆性がありません。これは、unpack が最上位のニブルで先行ゼロを返す可能性があるためです。

['ABC'].pack('H*') == ['0ABC'].pack('H*') # false

ここで、整数から変換した後に偶数のニブルが得られたかどうかを確認する必要があります。必要に応じてゼロで埋めます。

例で更新:

s = "\x01\x1D\x9A".force_encoding 'binary' # "\x01\x1D\x9A"
s.unpack('H*') # ["011d9a"]
s.unpack('H*')[0].to_i(16) # 73114

それでは、デコードしましょう:

s.unpack('H*')[0].to_i(16).to_s(16) # "11d9a" — notice that leading zero is gone
[s.unpack('H*')[0].to_i(16).to_s(16)].pack('H*') # "\x11\xD9\xA0"
[s.unpack('H*')[0].to_i(16).to_s(16)].pack('H*') == s # false, obviously

つまり、最初と同じ値にデコードできませんでした。

4

1 に答える 1

0

残念ながら、私はRubyについてまったく知識がありませんが、確認できるアイデアはあります...

.to_s(16) メソッドは、デフォルトのエンコーディングが異なる文字列に変換され、.pack('H*') の後に文字列を比較するときに問題になる可能性がありますか? これでうまくいくかもしれません: [s.unpack('H*')[0].to_i(16).to_s(16)].pack('H*').force_encoding 'binary' == s

そうしないと、先頭にゼロがあるニブルが、同じ文字列バイトとは異なるがゼロのない16進ニブルから変換された文字列バイトにどのように変換されるかを想像するのは困難です。

于 2012-04-18T15:52:42.580 に答える