二進(jìn)制與權(quán)限控制

二進(jìn)制與權(quán)限控制有什么關(guān)系

最近在做權(quán)限方面的設(shè)計(jì),很自然想到了二進(jìn)制的方案。
二進(jìn)制跟權(quán)限有什么關(guān)系?舉兩個(gè)例子大家就熟悉了:

  1. Linux的文件權(quán)限: 可執(zhí)行 001, 可寫(xiě) 010,可讀100,三種權(quán)限都有是111,也就是int(7)。
  2. PHP的錯(cuò)誤級(jí)別:E_ERROR = 00...001, E_WARNING = 00...010, E_PARSE = 00...100。

優(yōu)勢(shì)在哪里

那么為什么要用二進(jìn)制來(lái)控制權(quán)限呢?我覺(jué)得最明顯的優(yōu)勢(shì)有兩個(gè):

1.易存儲(chǔ)易擴(kuò)展

假如現(xiàn)在要設(shè)計(jì)一個(gè)用戶權(quán)限系統(tǒng),分別有CRUD四種權(quán)限。那么最先想到的可能是在數(shù)據(jù)表里建4個(gè)tinyint字段,如下:

USSE_ID C_ABLE R_ABLE U_ABLE D_ABLE
12345 0 1 1 1
67890 1 1 1 1

這樣設(shè)計(jì)用是能用,但如果以后要新增一個(gè)權(quán)限類型,例如是發(fā)郵件的權(quán)限。那必須改數(shù)據(jù)表,新增一個(gè)EMAIL_ABLE字段。這樣的需求對(duì)此方案來(lái)說(shuō)是很恐怖的,基本不可擴(kuò)展。
我們換個(gè)思路,改為用二進(jìn)制來(lái)控制權(quán)限,那么只需要一個(gè)字段就足夠了。
首先把所有權(quán)限用二進(jìn)制定義好:

C_ABLE: 1 << 0 (int 1)
R_ABLE: 1 << 1 (int 2)
U_ABLE: 1 << 2 (int 4)
D_ABLE: 1 << 3 (int 8)
EMAIL_ABLE: 1 << 4 (int 16)

因?yàn)槎M(jìn)制也就是一個(gè)整數(shù),所以用一個(gè)int/longint字段就可以把所有權(quán)限表示出來(lái)。數(shù)據(jù)表設(shè)計(jì)如下:

USER_ID PERMISSONS
12345 7
67890 15

以后如要新增權(quán)限類型,定義好它的二進(jìn)制即可,不需要新增數(shù)據(jù)表字段,擴(kuò)展性大大增強(qiáng)。

2.權(quán)限控制簡(jiǎn)單

權(quán)限增減

相信大家對(duì)PHP的error_reporting()函數(shù)很熟悉。
新增錯(cuò)誤上報(bào)項(xiàng),用|符號(hào),例如:

error_reporting(E_ERROR | E_WARNING)

表示上報(bào)E_ERROR + E_WARNING
刪除錯(cuò)誤上報(bào)項(xiàng),用& ~,例如:

error_reporting(E_ALL & ~E_NOTICE)

表示在所有上報(bào)項(xiàng)中排除E_NOTICE。
所以只需要用三個(gè)位運(yùn)算符就可以實(shí)現(xiàn)權(quán)限的增減控制,實(shí)現(xiàn)復(fù)雜權(quán)限的疊加。

權(quán)限判斷

最后一個(gè)問(wèn)題來(lái)了。在二進(jìn)制方案里,用戶的最終權(quán)限是一個(gè)整數(shù),那如何判斷該用戶是否擁有某個(gè)權(quán)限呢?
我們先看看PHP的error_reporting機(jī)制是怎么做的,見(jiàn)源碼:
https://github.com/php/php-src/blob/PHP-5.4.1/Zend/zend.c#L1080


留意#1080行,其實(shí)就是用了一個(gè)&運(yùn)算符。
假設(shè)用戶設(shè)置如下:error_reporting(E_NOTICE | E_WARNING)。判斷用戶是否需要上報(bào)某種類型錯(cuò)誤,執(zhí)行以下運(yùn)算即可:

//需要上報(bào)
if((E_NOTICE | E_WARNING) & E_NOTICE)       //為true,表示需要上報(bào)E_NOTICE,即擁有某權(quán)限
 
//不需要上報(bào)
if(!((E_NOTICE | E_WARNING) & E_ERROR))     //為false,表示不需要上報(bào)E_ERROR,即沒(méi)有某權(quán)限

至于為什么要用&運(yùn)算,大家把它們的二進(jìn)制寫(xiě)出來(lái)算一遍就一目了然了,這里不作展開(kāi)。

結(jié)論

用二進(jìn)制來(lái)做權(quán)限控制是一個(gè)非常經(jīng)典的方案,也有廣泛的使用場(chǎng)景,大家多加參考。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 國(guó)家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說(shuō)閱讀 12,391評(píng)論 6 13
  • 內(nèi)存是計(jì)算機(jī)非常關(guān)鍵的部件之一,是暫時(shí)存儲(chǔ)程序以及數(shù)據(jù)的空間,CPU只有有限的寄存器可以用于 存儲(chǔ)計(jì)算數(shù)據(jù),而大部...
    dreamer_lk閱讀 1,621評(píng)論 2 10
  • 觀其大綱 page 01 基礎(chǔ)知識(shí) 1 MySQL數(shù)據(jù)庫(kù)概要 2 簡(jiǎn)單MySQL環(huán)境 3 數(shù)據(jù)的存儲(chǔ)和獲取 4 M...
    周少言閱讀 3,255評(píng)論 0 33
  • 我來(lái)了,從你的全世界路過(guò),看過(guò)你看過(guò)的詩(shī),聽(tīng)過(guò)你愛(ài)的歌,你還在等她么?可否回頭,看看在等你的我 1. 走過(guò)你走的地...
    蕭娜閱讀 1,375評(píng)論 107 34
  • 看這本書(shū)時(shí)心里是有些不爽的,當(dāng)年日本侵入中華初始,每個(gè)戰(zhàn)爭(zhēng)都是節(jié)節(jié)的敗退,不是實(shí)力不足而是各自的利益集團(tuán)所在,當(dāng)打...
    奔騰君閱讀 451評(píng)論 0 0

友情鏈接更多精彩內(nèi)容