在實際應用中能夠作用戶權限的應用 |
002 |
我這裏說到的權限管理辦法是一個廣泛採用的方法,主要是使用到」位運行符」操做,& 位與運算符、| 位或運行符。參與運算的若是是10進制數,則會被轉換至2進制數參與運算,而後計算結果會再轉換爲10進制數輸出。 |
003 |
它的權限值是這樣的 |
004 |
2^0=1,相應2進數爲」0001″(在這裏^我表示成」次方」,即:2的0次方,下同) |
005 |
006 |
2^1=2,相應2進數爲」0010″ |
007 |
2^2=4,相應2進數爲」0100″ |
008 |
2^3=8,相應2進數爲」1000″ |
009 |
要判斷一個數在某些數範圍內就可使用 & 運算符(數值從上面的表中得來) |
010 |
如:7=4|2|1 (你也能夠簡單理解成7=4+2+1) |
011 |
用 & 來操做,能夠知道7&四、7&二、7&1都是真的,而若是7&8則是假的 |
012 |
&、| 不熟悉的就要去查查手冊,看看是怎麼用的了 |
013 |
下面來看例子吧: |
014 |
// 賦予權限值-->刪除:八、上傳:四、寫入:二、只讀:1 |
015 |
define(「mDELETE」,8); |
016 |
define(「mUPLOAD」,4); |
017 |
define(「mWRITE」,2); |
018 |
define(「mREAD」,1); |
019 |
//vvvvvvvvvvvvv使用說明vvvvvvvvvvvvv |
020 |
//部門經理的權限爲(假設它擁有此部門的全部權限),| 是位或運行符,不熟悉的就查查資料 |
021 |
echo mDELETE|mUPLOAD|mWRITE|mREAD ,」 |
022 |
「; // 至關因而把上面的權限值加起來:8+4+2+1=15 |
023 |
// 設我只有 upload 和 read 權限,則 |
024 |
echo mUPLOAD|mREAD ,」 |
025 |
「; //至關因而把上傳、只讀的權限值分別相加:4+1=5 |
026 |
/* |
027 |
*賦予它多個權限就分別取得權限值相加,又好比某位員工擁有除了刪除外的權限其他都擁有,那它的權限值是多少? |
028 |
*應該是:4+2+1=7 |
029 |
*明白了怎麼賦值給權限吧? |
030 |
*/ |
031 |
//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ |
032 |
//判斷某人的權限可用,設權限值在$key中 |
033 |
/* |
034 |
*判斷權限用&位與符, |
035 |
*/ |
036 |
$key = 13; //13=8+4+1 |
037 |
if ( $key & mDELETE) echo 「有刪除權限 |
038 |
「; //8 |
039 |
if ( $key & mUPLOAD) echo 「有上傳權限 |
040 |
「; //4 |
041 |
$a = $key & mWRITE; echo 「有寫權限 |
042 |
「. $a ; //無此權限 |
043 |
if ( $key & mREAD) echo 「有讀權限 |
044 |
「; //1 |
045 |
?> |
046 |
OK,權限分值的這其中一個算法就是這樣的,能夠說是簡單高效。也不知你們明白沒有,不明白也不要緊,記住例子就好了。前提就是作好權限值的分佈,即那個一、二、四、八、16….(這裏還有個順序問題,越高級的權限就要越高的權限值,好比上面的例子所演示的刪除權限)。有了權限分佈表就能夠肯定給某我的什麼權限了,你簡單的理解成要哪一個權限就加上相應的權限值吧。 |
047 |
這個方法很好用的,缺點就是若是權限分佈得細的話,那麼權限值會愈來愈大,你本身想一想,2的幾回方、若是全部的權限都要則是所有相加。不過對於通常的權限來講這個已經足夠了。 |
048 |
049 |
下面是些簡單應用舉例 |
050 |
051 |
(1) 判斷int型變量a是奇數仍是偶數 |
052 |
053 |
a&1 = 0 偶數 |
054 |
055 |
a&1 = 1 奇數 |
056 |
057 |
(2) 取int型變量a的第k位 (k=0,1,2……sizeof(int)),即a>>k&1 |
058 |
059 |
(3) 將int型變量a的第k位清0,即a=a&~(1< |
060 |
061 |
<> |
062 |
063 |
(4) 將int型變量a的第k位置1, 即a=a|(1< |
064 |
065 |
<> |
066 |
067 |
(5) int型變量循環左移k次,即a=a<>16-k (設sizeof(int)=16) |
068 |
069 |
(6) int型變量a循環右移k次,即a=a>>k|a<<16-k (設sizeof(int)=16) |
070 |
071 |
(7)整數的平均值 |
072 |
073 |
對於兩個整數x,y,若是用 (x+y)/2 求平均值,會產生溢出,由於 x+y 可能會大於INT_MAX,可是咱們知道它們的平均值是確定不會溢出的,咱們用以下算法: |
074 |
075 |
int average(int x, int y) //返回X,Y 的平均值 |
076 |
077 |
{ |
078 |
079 |
return (x&y)+((x^y)>>1); |
080 |
081 |
} |
082 |
083 |
(8)判斷一個整數是否是2的冪,對於一個數 x >= 0,判斷他是否是2的冪 |
084 |
085 |
boolean power2(int x) |
086 |
087 |
{ |
088 |
089 |
return ((x&(x-1))==0)&&(x!=0); |
090 |
091 |
} |
092 |
093 |
(9)不用temp交換兩個整數 |
094 |
095 |
void swap(int x , int y) |
096 |
097 |
{ |
098 |
099 |
x ^= y; |
100 |
101 |
y ^= x; |
102 |
103 |
x ^= y; |
104 |
105 |
} |
106 |
107 |
(10)計算絕對值 |
108 |
109 |
int abs ( int x ) |
110 |
111 |
{ |
112 |
113 |
int y ; |
114 |
115 |
y = x >> 31 ; |
116 |
117 |
return (x^y)-y ; //or: (x+y)^y |
118 |
119 |
} |
120 |
121 |
(11)取模運算轉化成位運算 (在不產生溢出的狀況下) |
122 |
123 |
a % (2^n) 等價於 a & (2^n – 1) |
124 |
125 |
(12)乘法運算轉化成位運算 (在不產生溢出的狀況下) |
126 |
127 |
a * (2^n) 等價於 a<< n |
128 |
129 |
(13)除法運算轉化成位運算 (在不產生溢出的狀況下) |
130 |
131 |
a / (2^n) 等價於 a>> n |
132 |
133 |
例: 12/8 == 12>>3 |
134 |
135 |
(14) a % 2 等價於 a & 1 |
136 |
137 |
(15) if (x == a) x= b; |
138 |
139 |
else x= a; |
140 |
141 |
等價於 x= a ^ b ^ x; |
142 |
143 |
(16) x 的 相反數 表示爲 (~x+1) |
144 |
145 |
在32位系統上不要右移超過32位,不要在結果可能超過 32 位的狀況下左移 |