Tcl – バイナリデータの操作(2) -binary format-

binary format

[書式]

binary format formatString ?arg arg ...?

binary formatは、formatString で指定した書式に従って arg で指定した文字列をバイナリデータに変換を行い、変換したバイナリデータを返します。

formatStringの指定方法

例.

binary fomat a3a2  Good morning!
=> Goomo

formatString のフィールドは”a3″と”a2″の2つあります。それに対応する値も”Good”と”morning!”の2つあります

フィールドの最初の単一文字は変換方法を示すタイプです。その後に続く数字は変換を繰り返す回数(count)を表します。数字の代わりに”*”を使うと、対応するargの文字列すべて変換します。

タイプ”a”は、文字列ageのcount桁数のバイト列(バイナリデータ)に変換して返します。例の場合は、Gooの3文字とmoの2文字をバイト列にしたものが返されます。

Goomoの文字を16進数で表現すると以下のようになります。

47 6f 6f 6d 6f
G  o  o  m  o

よって、\x47\x6f\x6f\x6d\x6f に相当するバイナリ値を返します。

例では、アスキコードの範囲内の文字なので、変換後も文字として見えていますが、漢字などアスキコードの範囲外の文字であれば、返されたバイナリデータは文字化けします。

メモ

例の結果を見ると、一見、文字から文字へ変換しているように見えますが、文字データからバイナリデータに変換しています。

タイプに指定できる種類は以下のようなものがあります。


a
文字列argをcount桁分、バイナリ値で出力します。

argがcountより少ない場合、00で埋められます。countより多い場合は、切り捨てられます。countを省略した場合、1文字が変換されます。countが”*”の場合、全て変換されます。

例.

binary format a8  Hello!
=> Hello!

\x48\x65\x6c\x6c\x6f\x21\x00\x00 に相当するバイナリ値を返します。

\x48\x65\x6c\x6c\x6f\x21\x00\x00
  H   e   l   l   o   !  

※日本語を扱う場合、「binaryコマンドの日本語の扱いについて」を参照してください。


A
argがcountより少ない場合、スペースで埋められます。それ以外は、aと同じ。

例.

binary format a8  Hello!
=> Hello!

\x48\x65\x6c\x6c\x6f\x21\x20\x20 に相当するバイナリ値を返します。

\x48\x65\x6c\x6c\x6f\x21\x20\x20
  H   e   l   l   o   !  空白 空白

b
2進数表記の文字列(age)をcount桁分、バイト単位でlow-to-high順に出力します。

argは文字”1″と”0″で指定します。argがcountより少ない場合、残りのビットは、ゼロで埋められます。countより多い場合は、切り捨てられます。countを省略した場合、1ビットが出力されます。countが”*”の場合、全て出力されます。出力されたビット数がバイト境界で終了しない場合、残りのビットはゼロで埋められます。

例.

binary format b8b* 110010 011100110101
=> \x13\xce\x0a に相当するバイナリ値を返します。

[参考]
ビット・桁の数え方

      上位 下位
            7654 3210 ←bit ※計算機により異なります。
  8桁目→ 1111 1110 ←1桁目
       F    E

例の場合

 |-------|  |-------| |-------| ← バイト境界
 1100 1000  0111 0011 0101 0000 ←  2進数
    C    8     7    3    5    0  ← 16進数

バイト内でlow-to-high順なので通常とは逆に数えます。

 0001 0011  1100 1110  0000 1010 ←  2進数
    1    3     C    E    0    A   ← 16進数

赤線:不足分を0で埋められています。

※最上位ビット(MSB)を0とするか最下位ビット(LSB)を0とするかは計算機により違います。
最上位ビット
https://ja.wikipedia.org/wiki/最上位ビット
エンディアン
https://ja.wikipedia.org/wiki/エンディアン


B
ビットが各バイト内のhigh-to-lowの順番で出力されることを除いて、bと同じです。

例.

binary format B8B* 110010 011100110101
=> \xc8\x73\x50 に相当するバイナリ値を返します。

h
16進数表記の文字列(age)をcount桁分、バイト単位でlow-to-high順に出力します。

argは文字「0123456789abcdefABCDEF」で指定します。
変換されるバイナリ値は、argで指定した16進数表記の文字2つからバイト値を求め、バイト内で下位から上位(low-to-high)の順で出力されます。


argの桁数がcountより少ない場合は、残りの桁にゼロが使用されます。argが指定された桁数より多い場合、余分な桁は無視されます。countが*の場合、arg内のすべての数字が変換されます。


変換された桁数がバイト境界で終了しない場合、残りの4ビットはゼロになります。countが省略された場合、1桁が変換されます。

例1.

binary format h3h* AB def
=> \xba\x00\xed\x0f に相当するバイナリ値を返します。

例2.

binary format h AB
=> \x0a に相当するバイナリ値を返します。

[参考]

例1

上位 下位  
1010 1011      → 下位・上位順の為、BAのバイナリ値が出力される。
 A    B          countが3かつバイト境界でない為、残りの桁が00になる。

上位 下位 上位
1101 1110 1111 → 下位・上位順の為、edのバイナリ値が出力される。
 d    e    f   最後の桁は、バイト境界でないので、f0になり、
           下位・上位順の為、0fのバイナリ値が出力される。

例2.

countが省略されている為、1桁の”A”のみ変換され、残りの桁”B”の4ビットは変換されずにゼロになります。


H
バイト内で上位から下位(high-to-low)の順で出力されることを除いて、hと同じです。

例.1

binary format h3h* AB def
=> \xab\x00\xde\xf0 に相当するバイナリ値を返します。

例2.

binary format h AB
=> \xa0 に相当するバイナリ値を返します。

c
1つ以上の8ビット整数値を変換します。

argは整数値で指定します。countが指定されていない場合、argは1つの整数値でなければなりません。countが指定されている場合、argは、その数のリストで指定します。各要素の下位8ビットが1バイトのバイナリ値として出力されます。

countが*の場合、全ての要素が変換されます。リスト内の要素数が、countより大きい場合、余分な要素は無視されます。リスト内の要素数が、countより少ない場合、エラーになります。

例.

binary format c3cc* {3 -3 128 1} 260 {2 5}
=> \x03\xfd\x80\x04\x02\x05 に相当するバイナリ値を返します。

以下はエラーになります。

binary format c {2 5}
=> expected integer but got "2 5"

binary fomat c3 {2 5}
=> number of elements in list does not match count

[参考]

   3 : 0000 0011
   -3 : 1111 1101 参:ビットごとのNOT(1の補数)のメモを参照
 128 : 1000 0000 16進で80
  1 : 0000 0001 countに3を指定しているので無視されます。
 260 : 0001 0000 0100 下位8ビットが変換対象の為、04を出力する。

s
1つ以上の16ビット整数値をリトルエンディアン(little-endian)順に出力します。

16ビット(2バイト)の内、最下位バイトを先に出力します。それ以外はcと同じです。

例.

binary format s3 {3 -3 258 1}
=> \x03\x00\xfd\xff\x02\x01 に相当するバイナリ値を返します。

[参考]

 258 : 0000 0001 0000 0010 16進で102
          0    1    0    2

S
1つ以上の16ビット整数値をビッグエンディアン(big-endian)順に出力します。

16ビット(2バイト)の内、最上位バイトを先に出力します。それ以外はsと同じです。

例.

binary format S3 {3 -3 258 1}
=> \x00\x03\xff\xfd\x01\x02 に相当するバイナリ値を返します。

t
Tclスクリプトが実行されているマシンのネイティブのバイト順で16ビット整数を出力することを除いて、sおよびSと同じです。

マシンのネイティブのバイト順が何であるかを判断するには、tcl_platform配列のbyteOrder要素を参照してください。

例.

puts $tcl_platform(byteOrder)
=> littleEndian

i
1つ以上の32ビット整数値をリトルエンディアン(little-endian)順に出力します。

32ビット(4バイト)の内、最下位バイトを先に出力します。それ以外はcと同じです。

例.

binary format i3 {3 -3 65536 1}
=> \x03\x00\x00\x00\xfd\xff\xff\xff\x00\x00\x01\x00
   に相当するバイナリ値を返します。

I
1つ以上の32ビット整数値をビッグエンディアン(big-endian)順に出力します。

32ビット(4バイト)の内、最上位バイトを先に出力します。それ以外はiと同じです。

例.

binary format I3 {3 -3 65536 1}
=> \x00\x00\x00\x03\xff\xff\xff\xfd\x00\x01\x00\x00
  に相当するバイナリ値を返します。

n
Tclスクリプトが実行されているマシンのネイティブのバイト順で32ビット整数を出力することを除いて、iおよびIと同じです。

マシンのネイティブのバイト順が何であるかを判断するには、tcl_platform配列のbyteOrder要素を参照してください。

例.

puts $tcl_platform(byteOrder)
=> littleEndian

w
1つ以上の64ビット整数値をリトルエンディアン(little-endian)順に出力します。

64ビット(8バイト)の内、最下位バイトを先に出力します。それ以外はcと同じです。

例.

binary format w 7810179016327718216
=> HelloTcl に相当するバイナリ値を返します。

[参考]
・16進数に変換すると

puts [format %x 7810179016327718216]
=> 6c63546f6c6c6548 
16進 :6c 63 54 6f 6c 6c 65 48 
ASCII: l  c  T  o  l  l  e  H 
=> 最下位バイトから出力すると HelloTcl

W
1つ以上の64ビット整数値をビッグエンディアン(big-endian)順に出力します。

64ビット(8バイト)の内、最上位バイトを先に出力します。それ以外はwと同じです。

例.

binary format Wc 4785469626960341345 110
=> BigEndian に相当するバイナリ値を返します。

[参考]
・16進数に変換すると

puts [format "%x %x" 4785469626960341345 110]
=> 426967456e646961 6e
16進 :42 69 67 45 6e 64 69 61 6e
ASCII: B  i  g  E  n  d  i  a  n
=> 最上位バイトから出力すると BigEndian

m
Tclスクリプトが実行されているマシンのネイティブのバイト順で64ビット整数を出力することを除いて、wおよびWと同じです。

マシンのネイティブのバイト順が何であるかを判断するには、tcl_platform配列のbyteOrder要素を参照してください。

例.

puts $tcl_platform(byteOrder)
=> littleEndian

f
1つ以上の単精度浮動小数点数を、マシンのネイティブ表現で出力します。

この表現はアーキテクチャ間で移植性がないため、ネットワーク上で浮動小数点数を通信するために使用しないでください。

浮動小数点数のサイズはアーキテクチャによって異なりますので、生成されるバイト数は異なります。

値がマシンのネイティブ表現をオーバーフローすると、システムによって定義されたFLT_MAXの値が代わりに使用されます。 Tclは内部で倍精度浮動小数点数を使用しているため、単精度への変換では精度がいくらか低下する可能性があります。

たとえば、Intel(R) Core(TM) i7-4770 CPU上で実行されているWindowsシステムでは、

binary format f2 {1.6 3.4}
=> \xcd\xcc\xcc\x3f\x9a\x99\x59\x40
   に相当するバイナリ値を返します。

r
単精度浮動小数点数をリトルエンディアン順に格納することを除いて、fと同じです。

この変換は、IEEE浮動小数点表現を使用するマシンで使用された場合にのみ意味のある出力を生成します(非常に一般的ですが、ユニバーサルではありません)。


R
単精度浮動小数点数をビッグエンディアン順に格納すること以外はrと同じです。


d
1つ以上の倍精度浮動小数点数を、マシンのネイティブ表現で出力します。それ以外は、fと同じです。

たとえば、Intel Pentiumプロセッサ上で実行されているWindowsシステムでは、

binary format d1 {1.6}
=> \x9a\x99\x99\x99\x99\x99\xf9\x3f
   に相当するバイナリ値を返します。

q
倍精度浮動小数点数をリトルエンディアン順に格納することを除いて、dと同じです。

この変換は、IEEE浮動小数点表現を使用するマシンで使用された場合にのみ意味のある出力を生成します(非常に一般的ですが、ユニバーサルではありません)。


Q
倍精度浮動小数点数をビッグエンディアン順で格納することを除いてqと同じです。


x
count個のnullバイトを出力します。countが指定されていない場合は、1バイトのnullを出力します。countが*の場合、エラーが発生します。

このタイプは引数を消費しません。 例えば、

binary format a3xa3x2a3 abc def ghi
=> abc
binary format a3xa3x2a3 abc def ghi
=> abc\000def\000\000ghi に相当するバイナリ値を返します。
0def
binary format a3xa3x2a3 abc def ghi
=> abc\000def\000\000ghi に相当するバイナリ値を返します。
0
binary format a3xa3x2a3 abc def ghi
=> abc\000def\000\000ghi に相当するバイナリ値を返します。
0ghi に相当するバイナリ値を返します。

X
出力データのカーソル位置をcountバイト後ろに戻します。

countが*または現在のカーソル位置よりも大きい場合、カ-ソル位置は0に配置され、出力されている次のバイト値が最初のバイト値になります。countが省略された場合、カーソル位置は1バイト戻ります。

このタイプは引数を消費しません。例えば

binary format a3X*a3X2a3 abc def ghi
=>  dghi に相当するバイナリ値を返します。

[参考]

a3 ---------> abc_ カーソル位置3
a3X* -------> abc  カーソル位置が0に戻る
a3X*a3 -----> def_ カーソル位置3
a3X*a3X2 ---> def  カーソル位置が1に戻る。2バイト(2文字分)戻る。
a3X*a3X2a3 -> dghi を返す。

@
countで指定された出力データの絶対位置にカーソルを移動します。

位置0は、出力ストリングの最初のバイトを表します。countがこれまでに格納された最後のバイトを超えた位置を参照している場合は、nullバイトが初期化されていない位置に配置され、カーソルは指定された位置に配置されます。

countが*の場合、カーソルは出力データの現在の末尾に移動します。 countを省略すると、エラーが発生します。

このタイプは引数を消費しません。 例えば、

binary format a5@2a1@*a3@10a1 abcde f ghi j
=> abfdeghi
binary format a5@2a1@*a3@10a1 abcde f ghi j
=> abfdeghi\000\000j に相当するバイナリ値を返します。
0
binary format a5@2a1@*a3@10a1 abcde f ghi j
=> abfdeghi\000\000j に相当するバイナリ値を返します。
0j に相当するバイナリ値を返します。

[参考]

a5 --------------> abcde_            カーソル位置5
a5@2 ------------> abcde             カーソル位置2
a5@2a1 ----------> abfde             カーソル位置3
a5@2a1@* --------> abfde_            カーソル位置5
a5@2a1@*a3 ------> abfdeghi_         カーソル位置8
a5@2a1@*a3@10 ---> abfdeghi
a5 --------------> abcde_            カーソル位置5
a5@2 ------------> abcde             カーソル位置2
a5@2a1 ----------> abfde             カーソル位置3
a5@2a1@* --------> abfde_            カーソル位置5
a5@2a1@*a3 ------> abfdeghi_         カーソル位置8
a5@2a1@*a3@10 ---> abfdeghi\000\000_ カーソル位置10
a5@2a1@*a3@10a1 -> abfdeghi\000\000j を返す。
0
a5 --------------> abcde_            カーソル位置5
a5@2 ------------> abcde             カーソル位置2
a5@2a1 ----------> abfde             カーソル位置3
a5@2a1@* --------> abfde_            カーソル位置5
a5@2a1@*a3 ------> abfdeghi_         カーソル位置8
a5@2a1@*a3@10 ---> abfdeghi\000\000_ カーソル位置10
a5@2a1@*a3@10a1 -> abfdeghi\000\000j を返す。
0_ カーソル位置10 a5@2a1@*a3@10a1 -> abfdeghi
a5 --------------> abcde_            カーソル位置5
a5@2 ------------> abcde             カーソル位置2
a5@2a1 ----------> abfde             カーソル位置3
a5@2a1@* --------> abfde_            カーソル位置5
a5@2a1@*a3 ------> abfdeghi_         カーソル位置8
a5@2a1@*a3@10 ---> abfdeghi\000\000_ カーソル位置10
a5@2a1@*a3@10a1 -> abfdeghi\000\000j を返す。
0
a5 --------------> abcde_            カーソル位置5
a5@2 ------------> abcde             カーソル位置2
a5@2a1 ----------> abfde             カーソル位置3
a5@2a1@* --------> abfde_            カーソル位置5
a5@2a1@*a3 ------> abfdeghi_         カーソル位置8
a5@2a1@*a3@10 ---> abfdeghi\000\000_ カーソル位置10
a5@2a1@*a3@10a1 -> abfdeghi\000\000j を返す。
0j を返す。

次ページは、「binaryコマンドの日本語の扱いについて」

コメント

タイトルとURLをコピーしました