ネタ本を新たに発掘しました。『マイコンとパズルの世界 BASICプログラミング頭の体操』〔小谷 善行, 産報出版, 1981.〕。
プロジェクトの本文や、活動報告についての感想、ご意見、ご質問を、ぜひコメントでお寄せいただければと思います。現在は支援募集期間中であり、本企画の実施期間ではないため、お寄せいただいた感想などについてはリターンとしてではなく、お返事や回答をさせていただきます。
また、私個人についてはこちらをご覧ください。
では本題、前回の続きです。
先の符号ビット表示のみを取り出し、そのまま並べてみます:
符号ビット表示
1111110 1111110
11111110 111111110
0 10
0 10
110 1110
110 1110
11110 111110
11110 111110
1111111110 11111111110
111110 11110
1110 110
1110 110
1110 110
10 0
10 0
10 0
さらに、これを8ビットずつの並びにしてみます:
2進表示
1111 1101 1111 1011 1111 1011
1111 1100 1001 0110 1110 1101
1101 1110 1111 1011 1101 1111
0111 1111 1101 1111 1111 1011
1110 1111 0111 0110 1110 1101
1101 1010 0100 1001
(最後に1ビット、1を付け加えています。)
16進表示
FD FB FB
FC 95 ED
DE FB DF
7F DF FB
EF 76 ED
DA 49
この場合、元の32バイトが、17バイトに収まっています。もっとも、これはデータの部分だけですが。
なお、今回は、圧縮の対象のデータを8bit固定長としましたが、可変長でも構わないことに注意してください。
さて、この16進表示だけでは、元に戻せないので、戻すための辞書も作りましょう。前回の投稿分の、「ここで、これらに次のようにbit単位の符号を割り当てたとします」にこのようなデータがありました:
値 回数 ビット列
00 2 1111110
01 1 11111110
80 1 111111110
02 5 0
40 5 10
04 5 110
20 5 1110
08 3 11110
10 3 111110
1F 1 1111111110
F8 1 11111111110
ここで「回数」は必要ないので削除します。ついでに「ビット列」と「値」も入れ替えてみましょう:
ビット列 値
1111110 00
11111110 01
111111110 80
0 02
10 40
110 04
1110 20
11110 08
111110 10
1111111110 1F
11111111110 F8
これを、ビット列の長さで並べ替えます:
ビット列 値
0 02
10 40
110 04
1110 20
11110 08
111110 10
1111110 00
11111110 01
111111110 80
1111111110 1F
11111111110 F8
続いて「値」もビット列に直しましょう:
ビット列 値 値のビット列
0 02 0000 0010
10 40 0100 0000
110 04 0000 0100
1110 20 0010 0000
11110 08 0000 1000
111110 10 0001 0000
1111110 00 0000 0000
11111110 01 0000 0001
111111110 80 1000 0000
1111111110 1F 0001 1111
11111111110 F8 1111 1000
さて、次にこの「ビット列」と「値のビット列」をくっつけます。この場合、「可変長 + 8ビット」という形式に決まっており、かつ「可変長」つまり「ビット列」の部分は “0” で終っていることに注意しましょう:
全体のビット列
0 0000 0010
10 0100 0000
110 0000 0100
1110 0010 0000
11110 0000 1000
111110 0001 0000
1111110 0000 0000
11111110 0000 0001
111111110 1000 0000
1111111110 0001 1111
11111111110 1111 1000
では、これを8ビットずつにくっつけたり分割したりします:
全体のビット列 2進表示
0000 0001 0100 1000 0001 1000
0001 0011 1000 1000 0011 1100
0001 0001 1111 0000 1000 0111
1110 0000 0000 1111 1110 0000
0001 1111 1111 0100 0000 0111
1111 1100 0011 1111 1111 1111
1011 1110 0011 1111
(最後に1を6こ付け加えました。)
これにより辞書の部分は20バイトとなります。
では、これからもとの「辞書」を再現できるかやってみましょう。
まず、1ビットめは「0」ですから、符号は「0」のみで、以下の8ビットは元の値です。その8ビットは「0000 0010」とわかります。その次のビット列は「10」で、それに続く8ビットは「0100 0000」だとわかります。さらにその次のビット列は「110」で、それに続く8ビットは「0000 0100」だとわかります。以下略。
このようにすると、先のデータに対して辞書を加えて、17バイト + 20バイト = 37バイトとなりました。前回の投稿の「最後に8ビットごとの “□” と “■” の並びをそのままバイトに置き換えるとします」の箇所では32バイトでしたので、嬉しい結果ではありませんが、もとのバイト数が少なかったからというところでしょう。辞書は必要ですが、ここではデータ本体が32バイトに対して17バイトになったことでよしとしましょう。
これらの例は、すこしばかり不自然な面もありますが、データ表現やデータ圧縮の入口のネタには使えるのではないかと思います。もうすこし工夫が必要ですが。文字、それもアルファベットのようなシンプルなものではなく、絵や漢字にすると、面白さとしては違ってくるかと思います。
興味を持たれましたら、ぜひご支援や、コメントを頂ければと思います。