マスク (情報工学)

マスク (情報工学)の最新ニュースをまとめて検索!

情報工学におけるマスク: mask)とは、ビット単位の操作に使うデータである。ビットマスク (bit mask) とも。

マスクを使用すると、バイト、ニブル、ワードなどの複数のビットを同時にオンやオフにしたり、ビット単位にオン/オフを反転させたりできる。

目次

[編集] ビットマスク

[編集] ビットを 1 にマスクする

特定のビットをオンにするには、ビット単位のOR演算を行う。Y OR 1 = 1 であり、Y OR 0 = Y であることを思い出して欲しい。したがって、ビットを確実にオンにするには、1 との OR を行えばよい。変更しないビット位置では、0 との OR を行う。

例: 4番目のビットをオンにする

    10011101   10010101
 OR 00001000   00001000
  = 10011101   10011101

[編集] ビットを 0 にマスクする

OR演算ではオンのビットをオフにすることはできない。その場合はビット単位のANDを使う。1 との AND を行うと、値は単に元のままとなるので、Y AND 1 = Y である。しかし、0 との AND を行うと、必ず 0 になり Y AND 0 = 0 である。変更しないビット位置では、1 との AND を行えばよい。

例: 4番目のビットをオフにする

    10011101   10010101
AND 11110111   11110111
  = 10010101   10010101

[編集] 個々のビットの状態を調べる

ビットマスクを使うと、特定のビットだけを取り出してその状態を調べることができる。そのためには、ビット単位の AND を行って対象ビット以外を全てオフにすればよいので、上述したように対象外のビット位置は 0 との AND にすればよい。こうして得られた値を 0 と比較し、等しければ(0 ならば)そのビットはオフと分かるし、等しくなければオンだと分かる。このとき具体的にどういう値かを考慮する必要は無く、単に 0 かどうかだけで判断できる。

例: 4番目のビットの状態を調べる

    10011101   10010101
AND 00001000   00001000
  = 00001000   00000000

[編集] ビット値の反転

ここまでは、ビットをオンにする方法とオフにする方法を解説してきたが、両方を同時に行うにはどうすればよいだろうか。値がどうであろうと問題ではなく、単にビット列を反転させたい場合もある。この場合、XOR 演算を使う。XOR は、演算対象のビット(通常は2つ)のうち奇数個のビットが 1 の場合にのみ 1 を返す。つまり、2つのビットが共に 1 なら 0 を返すが、一方だけが 1 なら 1 を返す。したがって、反転させたいビット列について全て 1 とのビット単位の XOR を行えば、元のビット列を反転したビット列が得られる。元のビットが 1 なら 1 XOR 1 = 0 となるし、元のビットが 0 なら 0 XOR 1 = 1 となる。また Y XOR 0 = Y なので、XOR によるマスク操作ではマスクされていないビットはそのままであることが保証できる。

[編集] ビットマスクの使用例

[編集] 関数の引数

C言語のようなプログラミング言語では、ビットマスクは関数のブーリアン型の引数を一連の名前付きの値として渡すのに使える。例えば、グラフィックスAPIであるOpenGLには、glClear() というコマンドがある。これは画面や他のバッファをクリアするもので、4つのバッファ(color、depth、accumulation、stencil)をクリアできるので、これらを指定するのにブーリアン型の引数を4つ使ったAPIが考えられる。すると、その呼び出しは次のようになる。

glClear(1,1,0,0); // 実際の glClear とは異なる。

これでは、可読性が低く、何をしたいのかわかりにくい。そこで実際には特定ビット位置をオンにしたビットマスクに GL_COLOR_BUFFER_BITGL_DEPTH_BUFFER_BITGL_ACCUM_BUFFER_BITGL_STENCIL_BUFFER_BIT と名前を付け、glClear() を次のように宣言している。

void glClear(GLbitfield bits);

すると、この関数の呼び出しは次のようになる。

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

このような引数を持つ関数の内部では、個々のビットを取出すのに AND 演算を行っている。例えば、glClear() の実装は次のようになる。

void glClear(GLbitfield bits) {
  if (bits & GL_COLOR_BUFFER_BIT) {
    // color バッファをクリア
  }
  if (bits & GL_DEPTH_BUFFER_BIT) {
    // depth バッファをクリア
  }
  if (bits & GL_ACCUM_BUFFER_BIT) {
    // accumulation バッファをクリア
  }
  if (bits & GL_STENCIL_BUFFER_BIT) {
    // stencil バッファをクリア
  }
}

この手法の利点は、引数の個数を削減することでオーバーヘッドを削減できる点である。データとして受け渡しできる最小単位は1バイトなので、それぞれの操作を別々の引数で受け渡すと、引数当たり7ビットが無駄となり、余分なスタック領域を占有することになる。実際には引数は32ビットの整数であることが多く、その場合は32個のオプションを1つの引数で指定できる。しかし、この手法を単純に実装すると型安全ではなくなる。GLbitfield は単純に unsigned int で定義されているので、コンパイラは glClear(42)glClear(GL_POINTS) といった無意味な呼び出しがあってもエラーを検出できない。C++では、glClear が受け取る引数群をクラスとしてカプセル化でき、型安全性を保証できる(外部リンク参照)。

[編集] IPアドレスのマスク

IPアドレスのマスクは IP ACL (アクセス制御リスト)で許可されるものと拒否されるものを指定するのに使われる。インタフェース上のIPアドレスを設定するマスクは、先頭が255で左側の方が大きい値になる。例えば、IPアドレス 209.165.202.129 に対して 255.255.255.224 というマスクが対応する。IP ACL のマスクはその逆で、例えば 0.0.0.255 となる。これを逆マスク (inverse mask) あるいはワイルドカードマスク (wildcard mask) と呼ぶこともある。このマスク値をバイナリ(0と1)で表すと、アドレスのビット列のうちどの部分を処理するかが示されている。0となっているビット位置のアドレスビットは考慮され(一致する必要がある)、1となっているビット位置のアドレスビットは考慮しない。

マスクの例:

(処理すべきトラフィックの)ネットワークアドレス  10.1.1.0
マスク  0.0.0.255
ネットワークアドレス(バイナリ)  00001010.00000001.00000001.00000000
マスク(バイナリ)  00000000.00000000.00000000.11111111

バイナリ形式のマスクを見ると、先頭3オクテットは指定されたバイナリ形式のネットワークアドレス (00001010.00000001.00000001) と正確に一致しなければならない。最後尾にオクテットは考慮する必要はない (.11111111)。したがって、10.1.1. で始まるアドレスの全トラフィックを対象とし、最後尾のオクテットは考慮しない。つまり、このマスクでは 10.1.1.1 から 10.1.1.255 までのアドレスを処理する。

255.255.255.255 から通常のマスクを引き算すると ACL 用逆マスクが得られる。例えば、ネットワークアドレス 172.16.1.0 の通常のマスクが 255.255.255.0 の場合、逆マスクは次のように求められる。

255.255.255.255 - 255.255.255.0 (通常のマスク) = 0.0.0.255 (逆マスク)

アドレス 0.0.0.0 で逆マスクが 255.255.255.255 なら、アドレス範囲を指定しないことを示している。アドレス 10.1.1.2 で逆マスクが 0.0.0.0 なら唯一のホスト 10.1.1.2 だけを指す。

[編集] 画像マスク

スプライト(左)とマスク(右)のビットマップ画像

コンピュータグラフィックスにおいて、ある画像を何らかの背景画像の上に配置したい場合、背景画像を透過させる領域をマスクで指定する。この場合、配置対象の画像には2つのビットマップが存在する。画像内の描画しないピクセル(透明部分)に対応するビットを全て0にしたもの(実際の画像)と、描画する部分のピクセルを全て0とし、描画しない部分(透明部分)を全て1にした「マスク」である。右図の例で、黒いピクセルは全ビットが0で、白のピクセルは全ビットが1である。

このような画像を背景画像上に配置する場合、まず画面上のピクセルと画像マスクをビット単位のAND操作で合成する。すると、透明部分は背景がそのまま残り、画像を描画したい部分だけが0でクリアされる。

次に、実際の画像と背景画像をビット単位のOR操作で合成する。こうすると、画像のピクセル列は前の操作で背景が消された領域にぴったりと嵌まる。このようにして背景と画像を合成する。

背景画像
背景画像  
マスクを合成した状態
マスクを合成した状態  
完成した状態
完成した状態 

このような技法は、ポインティングデバイスのカーソルの描画、2次元のゲームのキャラクタなどの描画(スプライト)、GUIでのアイコンの描画、動画への文字の表示(スーパー)といった各種画像合成に使われている。

同様の目的の技術として、カラーパレットに透明色を設ける手法や、アルファチャンネルを用いる手法があり、その場合はピクセル画像のビットマスクは不要である。

[編集] ハッシュテーブル

ハッシュテーブルのためのハッシュ関数を作成する場合、大きな定義域の関数がよく使われる。そこからハッシュテーブルのインデックスを得るには、合同式の操作を行って配列のサイズに収まるようにする必要がある。しかし、ハッシュテーブルのサイズを2のべき乗に制限すれば、より単純なビットマスク操作に置換できる。

[編集] 関連項目

[編集] 外部リンク

最終更新 2009年8月4日 (火) 21:18 (日時は個人設定で未設定ならばUTC)。
【マスク (情報工学)】変更履歴

ご利用上の注意