2014年8月6日水曜日

わかりにくいのpack,unpack関数を実際に試してみた

Perlにはpack関数、unpack関数というのがあって、プログラムの基本書にも載っていたりはするのだが、あの解説を読んでもさっぱりわからないのでちょっと試してみることにした。

pack関数、unpack関数の意味不明な解説の例
http://www.tohoho-web.com/wwwperl2.htm#pack
別にこのサイトが悪いわけではなく、 どれ読んでもこんな意味不明の解説しか書かれていない。

今回必要な項目をちょっと抜粋してみる。

pack(template, list)
バイナリデータを生成する。templateでlistがどんな形式のデータなのか指定する。
後ろに数値を付けるとその個数分、アスタリスクを付けるとlistの最後までバイナリデータに変換する。

unpack(template, expr)
バイナリデータを解釈する

templateの例
c  符号付き1バイト数値(-128 ~ 127)
C  符号無し1バイト数値(0~255)
H  hex string(high nybble first)

全く何言ってるのかわかんねーな。バイナリデータって何だよ!って感じ。

今回試してみるプログラムで必要なのでASCIIコード表のURLも貼っておく。
http://e-words.jp/p/r-ascii.html

必要な部分を抜粋すると、アスキー文字コード一覧は下記の通り。
文字 10進数 16進数
%    37    25
&    38    26

さて、まずはunpack関数からPerlのワンライナーとその結果をいくつか打ってみよう。
$ perl -e '
my $val = unpack("H2","%");
print $val."\n";
'
25

$ perl -e '
my $val = unpack("H2","&");
print $val."\n";
'
26

$ perl -e '
my $val = unpack("H","&");
print $val."\n";
'
2

$ perl -e '
my $val = unpack("H2","&%");
print $val."\n";
'
26

$ perl -e '
my $val = unpack("H4","&%");
print $val."\n";
'
2625

$ perl -e '
my $val = unpack("H5","&%");
print $val."\n";
'
2625

つまりunpack("H2", 文字列)
は文字列をASCII文字コードの16進数表記に直して、それを2桁出力するという関数になる。


今度はpack関数に関してワンライナーを試してみる。

$ perl -e '
my $val = pack("c",hex(25));
print $val."\n";
'
%

$ perl -e '
my $val = pack("c",hex(26));
print $val."\n";
'
&

pack("c",10進数数値)は逆に数値からASCIIコードを生成している関数ということになる。

結論としては、数値をASCIIコードに変換するのがpack関数で、ASCIIコードを数値に変換しているのがunpack関数ということのようだ。今回の使い方だとね。