[PHP-users 7946] Re: Permissionのアルゴリズム

KOYAMA Tetsuji php-users@php.gr.jp
Thu, 06 Jun 2002 02:36:57 +0900


  小山です。
  アルゴリズムやそのヒントはいろんな方が回答されているので…。

At Wed, 05 Jun 2002 23:49:24 +0900,
Morikawa [encore-ann] <i@encore-ann.com> wrote:
> 
> もりかわ@似非PGです。
> 
> Unix のファイルシステムで、permission を 1,2,4 の組み合わせから
> 設定しているアルゴリズムについてお聞きしたいと思います。
> PHPと直接関係はないんですが、下記のようなスクリプトを作成して
> ある数値に含まれている要素を配列で返すようにしてみました。
>
> 見れば分かる通り、while で回しているのであまりすっきりとはしません。
> また、僕自身がどういうアルゴリズムに基づいているのか分からなくて
> (もちろん存在も知らなくて)、PHPの関数にあるのかどうかも調べきれ
> ません。

  1, 2, 4 と数値で考えると分かりにくいのかもしれませんが、これは「ビッ
トフラグ」という非常に良く使われる手法です。UNIX のファイルのアクセス
制限の場合は、基本は「読み込み」「書き込み」「実行」の3種類ですが、こ
れらの許可/不許可をそれぞれ 1 ビットで表しています。2進数で書くと

  +------- 読み込みを表すビット
  | +----- 書き込みを表すビット
  | | +--- 実行を表すビット
  V V V
  1 1 1

となっていて、それぞれのビットの状態を 10 進数で表すと

  意味		2進数	10進数
 ------------------------------
  実行だけ	 001     1
  書き込みだけ	 010     2
  読み込みだけ	 100     4

となるわけです。読み込み・書き込みを許可して、実行を許可しない場合

	2進数で 110 (10進数だと 4 + 2 = 6)

となり、各ビットの組み合わせで表現できることが分かります。(実際には所
有者、グループ、その他の各々に読み、書き、実行フラグが用意されています。)

  これらの状態を簡単に調べるために「ビット演算子」というものが用意され
ています。書き込みフラグを表す 010 の値を作るためには、001 という値の
ビットを 1 つだけ左にずらせばよいので、「左シフト」する << という演算
子を用いて

	1 << 1

と書けます。本来は 001 << 1 と書きたいところですが、PHPでは 2 進数を直
接記述する方法はないので、001 を10進数に直して 1 としています。同様に
読み込みフラグは

	1 << 2

と表せます。

  目的のアクセス許可状態を調べるには、特定のビットがオンになっているか
どうかを見ればいいわけですが、これには & 演算子を使います。例えばパー
ミッションが数値として $perm に保存されているとして、読み込み可能かど
うかを調べるには

	$readable = $perm & (1 << 2);

とすれば良いです。読み込み可能を表すビットがオフだと $readable は 0 に
なるので、簡単に状態を判断できます。

  一度 C 言語の入門本をご覧になると、よりいっそう理解できるでしょう。

-- 
	小山 哲志@ビート・クラフト
	koyama@beatcraft.com
	koyama@hoge.org