脳汁portal

アメリカ在住(だった)新米エンジニアがその日学んだIT知識を書き綴るブログ

Rubyのpack, unpackでエンディアンを指定する方法

前回に引き続きエンディアン関連のポストです。
ネットワークバイトオーダー・ビッグエンディアン・リトルエンディアンとは - 脳汁portal

BOMをデータの先頭に付与することで、データを受け取る側がエンディアンを判別できるようになると書きましたが、Rubyでは標準ライブラリでエンディアンの指定ができるのでその方法を書きます

コマンド

基本形
Array.pack(format)
String.unpack(format)
  • pack時のdataはarrayで指定する
  • unpack時のdataはStringで指定する
  • formatは以下参照


ビッグエンディアン
array.pack("N*")
string.unpack("N*")
  • Nの数はarrayのサイズ
    • *で無制限
    • 足りない場合はエラーになる
    • arrayの数の方が少ない場合は無視される


トルエンディアン
array.pack("V*")
string.unpack("V*")
  • VもNとほぼ一緒

ビッグエンディアン
$ irb
2.1.2 :001 > [1].pack("N")
 => "\x00\x00\x00\x01"
2.1.2 :002 > [1,2].pack("NN")
 => "\x00\x00\x00\x01\x00\x00\x00\x02"
2.1.2 :003 > "\x00\x00\x00\x01\x00\x00\x00\x02".unpack("NN")
 => [1, 2]


トルエンディアン
$ irb
2.1.2 :001 > [1].pack("V")
 => "\x01\x00\x00\x00"
2.1.2 :002 > [1,2].pack("V*")
 => "\x01\x00\x00\x00\x02\x00\x00\x00"
2.1.2 :003 > "\x01\x00\x00\x00\x02\x00\x00\x00".unpack("VV")
 => [1, 2]

# ちなみにformatを間違えると・・・
2.1.2 :004 > "\x01\x00\x00\x00\x02\x00\x00\x00".unpack("NN")
 => [16777216, 33554432] ### 正しい値がとれません