有讀過初中數學都會接觸過二進位數,如果知道什麼是二進位數的話可以先找找二進位數介紹的文章看看。
### 二進位數的特性
其實二進位和十進位也是數字,但是在某些情況下如果使用二進位數可以更易處理一些電腦上的問題。
如果有玩過 Linux 都會對 755, 777, 741 等數字很敏感 ! 沒錯,這是檔案的權限。其實在背後也是使用了二進位數的特性。
R(read) W(write) X(execute) 分別使用了三支 bit 來記錄獨立的權限。
|R(read)|W(write)|X(execute)|
|---|
|1|1|1|
而三個 bit 組成的二進位數就是它的權限代表數。其實就只有以下這 8 個組合 :
|R(read)|W(write)|X(execute)|decimal number|
|---|
|0|0|0|0|
|0|0|1|1|
|0|1|0|2|
|0|1|1|3|
|1|0|0|4|
|1|0|1|5|
|1|1|0|6|
|1|1|1|7|
0 代表完全沒有權限,7就代表最大的權限。從表格中你可以看到真的可以用 0-7 每一個數字代表一種權限的組合,而且是一定不會重覆的。以這樣的方法來管理權限系統,是可以以最少的 data size 來儲存權限資料。
### 實際使用
上面我們知道了如果把權限用數字的特情來儲存起來,但是在真正應用時我們應如何使用邏輯來判定這個數字是否有權限?
### And 特性
通過對一個二進位數使用 and 時,我們可以得最它們之間的共同值。以下作三個例子 :
|||||
|---|
||0|0|1|
|&|0|0|1|
||0|0|1|
> 001 & 001 = 001
|||||
|---|
||0|1|1|
|&|0|1|0|
||0|1|0|
> 011 & 010 = 010
|||||
|---|
||0|1|1|
|&|1|0|0|
||1|0|0|
> 011 & 100 = 000
And 特性會在兩者數值之間找出共有的保留,而非共有的就會捨去。
### 實作
使用這個特性,我們可以把系統的功能需要權限設為一個常數。
```js
// read
const READ = 0b100;
// write
const WRITE = 0b010;
// execute
const EXECUTE = 0b001;
```
然後每一個 User 有自己的權限儲存在自己的 `rights` 資料內。
```js
// new user
var user = new User();
// set user rights
user.rights = 0b100;
```
然後在 user 使用功能時,對 user 的權限進行檢查:
```js
// read function
function read(user) {
// check permission
if( (READ & user.rights) !== READ) {
throw new Error('permission denied');
}
// do something
}
```
我們只需要使用 & 特性,就可以檢查 user 有沒有足夠的權限訪問了 !!