2017-04-25 7 views
0

私は[1, 0, 11, 0, 4, 0, 106, 211, 169, 1, 0, 12, 0, 8, 0, 1, 26, 25, 32, 189, 77, 216, 1, 0, 1, 0, 4, 0, 0, 0, 0, 12, 15]の配列を持っています。バイナリ配列をASCII英数字文字列に変換するRubyメソッドが必要

ロギング用の文字列バージョンを作成するのが大好きです。私の最終結果は"01000B0004006AD3..."

です。各配列のバイト値を取り、バイト値のASCII表現で文字列をパックする簡単な方法が見つかりませんでした。

私の解決策は面倒です。私は、ソリューションを滑らかにするためのアドバイスを感謝します。

array.each {|x| 
    value = (x>>4)&0x0f 
    if(value>9) then 
    result_string.concat (value-0x0a + 'A'.ord).chr 
    else 
    result_string.concat (value + '0'.ord).chr 
    end 
    value = (x)&0x0f 
    if(value>9) then 
    result_string.concat (value-0x0a + 'A'.ord).chr 
    else 
    result_string.concat (value + '0'.ord).chr 
    end 
} 

答えて

2

あなたの質問は非常に明確ではありませんが、私はこのような何かを推測、あなたが探しているものをされています。二つのうちの一つは、より多くのです

array.map {|n| n.to_s(16).rjust(2, '0').upcase }.join 
#=> "01000B0004006AD3A901000C000800011A1920BD4DD80100010004000000000C0F" 

または

array.map(&'%02X'.method(:%)).join 
#=> "01000B0004006AD3A901000C000800011A1920BD4DD80100010004000000000C0F" 

どのあなたの読者がsprintfスタイルの書式文字列にどれほど馴染んでいるかによります。

+0

病気ルビースキルWRT '& '%02X'.method(:%)' – naomik

+0

に感謝イェルクWミッターク – Roman

0

私はあなたが進またはBASE64にこだわるお勧めの代わりに、独自のフォーマット

dat = [1, 0, 11, 0, 4, 0, 106, 211, 169, 1, 0, 12, 0, 8, 0, 1, 26, 25, 32, 189, 77, 216, 1, 0, 1, 0, 4, 0, 0, 0, 0, 12, 15] 

hex = dat.map { |x| sprintf('%02x', x) }.join 
# => 01000b0004006ad3a901000c000800011a1920bd4dd80100010004000000000c0f 

Base64で

require 'base64' 
base64 = Base64.encode64(dat.pack('c*')) 
# => AQALAAQAatOpAQAMAAgAARoZIL1N2AEAAQAEAAAAAAwP\n 

Proquiを作るかもしれませんnts

何ですか? Proquintsは発音可能な一意の識別子で、バイナリデータの読み取り/通信に最適です。あなたのケースでは、多分あなたはここ30+バイトを扱っているが、彼らは全体のプロセスがあまりにも可逆的である。もちろん、

# proquint.rb 
# adapted to ruby from https://github.com/deoxxa/proquint 
module Proquint 
    C = %w(b d f g h j k l m n p r s t v z) 
    V = %w(a i o u) 

    def self.encode (bytes) 
    bytes << 0 if bytes.size & 1 == 1 
    bytes.pack('c*').unpack('S*').reduce([]) do |acc, n| 
     c1 = n   & 0x0f 
     v1 = (n >> 4) & 0x03 
     c2 = (n >> 6) & 0x0f 
     v2 = (n >> 10) & 0x03 
     c3 = (n >> 12) & 0x0f 
     acc << C[c1] + V[v1] + C[c2] + V[v2] + C[c3] 
    end.join('-') 
    end 

    def decode str 
    # learner's exercise 
    # or see some proquint library (eg) https://github.com/deoxxa/proquint 
    end 
end 

Proquint.encode dat 
# => dabab-rabab-habab-potat-nokab-babub-babob-bahab-pihod-bohur-tadot-dabab-dabab-habab-babab-babub-zabab 

小さいバイト文字列のために非常に適しているではない最高のため。あなたはそれを必要としないかもしれないので、私は学習者のための練習としてそれを残しておきます

これは特にIPアドレスやその他の短いバイナリブロブのようなものにはうってつけです。あなたは彼らのproquintの形で一般的なバイト列を見るようにあなたは

Proquint.encode [192, 168, 11, 51] # bagop-rasag 
Proquint.encode [192, 168, 11, 52] # bagop-rabig 
Proquint.encode [192, 168, 11, 66] # bagop-ramah 
Proquint.encode [192, 168, 22, 19] # bagop-kisad 
Proquint.encode [192, 168, 22, 20] # bagop-kibid 
+0

@ありがとうございます。私は完全に間隔を置いてsprintf :)まさに私は後だった! – Roman

+0

ローマ、私はあなたを驚かせる別の答えを加えました。助けてくれたら教えてください^ _^ – naomik

+0

私はこれが大好きです。それは私に消化する時間がかかります。私はルビーを使用して戻ってきて、それを愛しています:) – Roman

2

それは実際にはかなり簡単ですあまりにも経験を得る:

整数値( C)を使用してバイトをパックし、Hexに結果の文字列をアンパック
def hexpack(data) 
    data.pack('C*').unpack('H*')[0] 
end 

H)。実際には:

hexpack([1, 0, 11, 0, 4, 0, 106, 211, 169, 1, 0, 12, 0, 8, 0, 1, 26, 25, 32, 189, 77, 216, 1, 0, 1, 0, 4, 0, 0, 0, 0, 12, 15]) 
# => "01000b0004006ad3a901000c000800011a1920bd4dd80100010004000000000c0f" 
関連する問題