”位運算“符進行權限設計

今天在羣裏聽到別人說 位操作能進行權限設計 what ???好奇心就來了 ;立馬查資料看看;在這裏分享給大家;

什麼是位運算

主要是使用到"位運行符"操作,& “與”運算符、|“或“運行符、^ ”異或“位運算符,還有>>“右移”運算符、<<”左移“運算符。參與運算的如果是10進制數,則會被轉換至2進制數參與運算,然後計算結果會再轉換爲10進制數輸出。(但是一般10進制對不齊,會寫2進制或者16進制的int類型數據)

位運算概況

符號 描述 運算規則
& 兩個位都爲1時,結果才爲1
l 兩個位都爲0時,結果才爲0
^ 異或 兩個位相同爲0,相異爲1
~ 取反 0變1,1變0
<< 左移 各二進位全部左移若干位,高位丟棄,低位補0
>> 右移 各二進位全部右移若干位,對無符號數,高位補0,有符號數,各編譯器處理方法不一樣,有的補符號位(算術右移),有的補0(邏輯右移)

20=1,相應2進數爲"0001"(這裏我表示成"次方",即:2的0次方,下同)
2^1=2,相應2進數爲"0010"
2^2=4,相應2進數爲"0100"
2^3=8,相應2進數爲"1000"

下面是常見的運算
1. 與運算(&)

0&0=0 0&1=0 1&0=0 1&1=1

3&5 即 0000 0011& 0000 0101 = 0000 0001,因此 3&5 的值得1。

  • 常用判斷:
  • 1)清零: 3&0
  • 2)取一個數的指定位
  • 3)判斷奇偶: if ((a & 1) == 0)代替if (a % 2 == 0)來判斷a是不是偶數

2. 或運算(|)

0|0=0 0|1=1 1|0=1 1|1=1
3|5 即 0000 0011| 0000 0101 = 0000 0111,因此,3|5的值得7。

  • 常用操作
  • 1)常用來對一個數據的某些位設置爲1,比如將數 X=1010 1110 的低4位設置爲1,只需要另找一個數Y,令Y的低4位爲1,其餘位爲0,即Y=0000 1111,然後將X與Y進行按位或運算(X|Y=1010 1111)即可得到。

3.異或運算(^)

0^0=0 0^1=1 1^0=1 1^1=0

  • 1、交換律
  • 2、結合律 (ab)c == a(bc)
  • 3、對於任何數x,都有 xx=0,x0=x
  • 4、自反性: abb=a^0=a;

4.左移運算符(<<)
定義:將一個運算對象的各二進制位全部左移若干位(左邊的二進制位丟棄,右邊補0)。
設 a=1010 1110,a = a<< 2 將a的二進制位左移2位、右補0,即得a=1011 1000。
若左移時捨棄的高位不包含1,則每左移一位,相當於該數乘以2。

5.右移運算符(>>)
定義:將一個數的各二進制位全部右移若干位,正數左補0,負數左補1,右邊丟棄。
例如:a=a>>2 將a的二進制位右移2位,左補0 或者 左補1得看被移數是正還是負。
操作數每右移一位,相當於該數除以2。

優點

位運算的運算對象是二進制的位,速度快,效率高,而且節省存儲空間,位運算做權限控制又相當地靈活。Linux系統的文件權限的實現方式,就是採用了位運算

缺點

位運算也有很大的侷限,因爲在32位計算機上,位移不能超過32次,這就要求權限數量不超過32種。

示例1

比如後臺工具的管理權限

//定於權限 2的n次方
var ADD = 1; // 增加權限
var UPD = 2; // 修改權限
var SEL = 4; // 查找權限
var DEL = 8; // 刪除權限

// 給予某種權限用到"位或"運算符
var GROUP_A = ADD | UPD | SEL | DEL; // A 擁有增刪改查權限
var GROUP_B = ADD | UPD | SEL; // B 擁有增改查權限
var GROUP_C = ADD | UPD; // C 擁有增改權限

// 禁止某種權限用"位與"和"位非"運算符
$GROUP_D = GROUP_C & ~UPD; // D 只擁有了增權限


//檢測某個用戶是否有這個權限
console.log("A用戶組成員是否有增加權限"+ ((GROUP_A & ADD) > 0))
console.log("A用戶組成員是否有刪除權限"+ ((GROUP_A & DEL) > 0))

console.log("B用戶組成員是否有增加權限"+ ((GROUP_B & ADD) > 0))
console.log("B用戶組成員是否有刪除權限"+ ((GROUP_B & DEL) > 0))

console.log("C用戶組成員是否有增加權限"+ ((GROUP_C & ADD) > 0))
console.log("C用戶組成員是否有刪除權限"+ ((GROUP_C & DEL) > 0))

console.log("D用戶組成員是否有增加權限"+ ((GROUP_C & ADD) > 0))
console.log("D用戶組成員是否有刪除權限"+ ((GROUP_C & DEL) > 0))

示例2

在Linux文件系統中,一個用戶對文件或目錄所擁有的權限分爲三種:“可讀”、“可寫"和"可執行”,分別用 1 、2 和 4 來表示,它們之間可以任意組合:有"可讀"、“可寫"權限就用 3 來表示(1 + 2 = 3);有"可讀”、"可執行"權限就用5來表示(1 + 4 = 5),三種權限全部擁有就用 7 表示(1 + 2 + 4 = 7)
實際上,這種運算是基於二進制的。

在這裏插入圖片描述
假設可執行、可寫、可讀三種權限分別對應三個狀態位,如果用戶具有某種權限,那麼將對應的狀態位標識爲"1",反之則標識爲"0"

代碼示例

//定義權限
var READ = 1<< 0; // 把可讀權限放在最右邊
var WRITE = 1<<1; // 可讀權限向左移一位
var EXCUTE = 1<<2; // 可執行權限向左移兩位

//賦予權限
var USER_TYL = READ | WRITE; //設置權限讀和寫

//驗證權限
console.log("USER_TYL可讀:"+ ((USER_TYL & READ) > 0));
console.log("USER_TYL可寫:"+ ((USER_TYL & WRITE) > 0));
console.log("USER_TYL可執行:"+ ((USER_TYL & EXCUTE) > 0));

總結

案例只是簡單的應用、一般項目中還是會寫2進制或者16進制的int類型數據;
如:0x0001

如:

var ADD = 0x0001; // 增加權限
var UPD = 0x0011; // 修改權限
var SEL = 0x0111; // 查找權限
var DEL = 0x1111; // 刪除權限
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章