C 中二進位制運算在許可權驗證的應用

2021-04-02 13:25:11 字數 2967 閱讀 8679

在我的另一篇文章中[委託在許可權驗證中的應用](見我的blog: http://blog.csdn.net/curllion/ 或http://spaces.msn.com/members/curllion)提到了乙個函式validateauthor,其實我以前見過這樣實現的,就是乙個許可權用乙個文本來表示,可能有「修改」、「填寫」、「審核」、「刪除」等等,這樣,對於每個使用者,在資料庫中,都有乙個字段,用來記錄這樣的許可權,某使用者許可權值可能是「修改|刪除|審核」,這樣,在查詢時,就會比較使用者許可權值中,有沒有包括乙個操作的名稱。這樣驗證許可權好辦,但我弄不明白,許可權的賦予與除去是如何實現的。

每乙個操作的許可權值,用乙個二進位制數來表示,每個許可權值,只能是(0),(10),(100),(1000),也就是說,是2的n次方,在mssql2000中,最大的整數是bigint型別的,最大可以表示64種操作。當然,這個是遠遠不夠的。所以可以給許可權分組。比如,可分為文員,主管,經理,那麼,我們最多可以分64個組,n0到n64組,第個組的許可權值(rolevalue)就可以用2的n次方來表示,所以,可以表示64許可權組了。這樣,不同的使用者,可能屬於1個或是多個許可權組,乙個許可權組,可能包括多個使用者,同理,對於乙個操作,可能會屬於多個許可權組,乙個許可權組,肯定要包括多個操作。

先說說我的做法的主要思路:

如何記錄乙個許可權呢,比如乙個使用者,他有乙個許可權值,最大可表示為2的64次方減1,所以,這個值有64個二進位制位,那麼,每一位要麼是0,要麼是1,所以,如果每一位表示一種許可權的話,就可以表示64種許可權了,因此,只要對指定的一位進行判斷是0還是1,就可以驗證使用者的許可權了。對於每乙個操作的許可權值,可以用乙個二進位制數來表示,每個許可權值,只能是(0),(10),(100),(1000),也就是說,是2的n次方,在mssql2000中,最大的整數是bigint型別的,最大可以表示64種操作。當然,這個是遠遠不夠的。所以可以給許可權分組。比如,可分為文員,主管,經理,那麼,我們最多可以分64個組,n0到n64組,第n個組的許可權值(rolevalue)就可以用2的n-1次方來表示,所以,可以表示64個許可權組了。這樣,不同的使用者,可以屬於1個或是多個許可權組,乙個許可權組,可能包括多個使用者,同理,對於乙個操作,可能會屬於多個許可權組,乙個許可權組,肯定要包括多個操作。因此,使用者與操作是通過許可權組聯絡以一起的。許可權組與使用者,與操作之間的對應關係,都是一對多的關係。

現在說說用c#來實現,不是在sql中實現。

在資料庫中的表:

操作組:

opname     oprolevalue

填寫             3            

修改             3

刪除           11

提交             6

審核           12

許可權組:

rolename  rolevalue

文員           1

主管           2

經理           4

總監           8

使用者資訊:

username userrolevalue

u1                5

在c#中:

long userrolevalue ;//使用者的許可權值,根據他屬於的許可權組,這個值會不同

long oprolevalue   ;//乙個操作的許可權值,根據他屬於的許可權組,這個值會不同

1、許可權的賦予(或運算)

userrolevalue = userrolevalue | oprolevalue

假設乙個使用者u1,他的初始許可權值為0(00000000)。如果要指定他有經理的許可權,經理的許可權值為4(00000100),在第三個二進位制位為1。

很顯然,userrolevalue =  0 | 4 ,值為4,如果u1要同時具有文員、主管、經理的許可權呢,

userrolevalue = 0 | 1   00000000 | 00000001  = 00000001

userrolevalue = 1 | 2   00000001 | 00000010  = 00000011

userrolevalue = 3 | 4   00000011 | 00000100  = 00000111

這樣,第1、2、3位都是1了,用 「或」的好處就是只改變指定位的值,如果使用者已經有了該許可權,再賦予一次,也不會出錯,但是直接簡單的用加法來做,這會出錯了,如下:

userrolevalue = 7 | 4   00000111 | 00000100  = 00000111

2、許可權的除去(求補、與運算)

userrolevalue = userrolevalue & (~oprolevalue)

假設乙個使用者u1,他的初始許可權值為7(00000111),說明他能做文員、主管、經理許可權組所能作的所有操作。如果不想讓他有主管許可權組能作的操作呢,那麼,就要把他的許可權值變為00000101,而主管許可權組的許可權值是00000010,顯然簡單的用減法,肯定也是不行的,但是先對00000010作補運算,可以得到11111101,再同00000111作與運算,就得到了00000101,這樣就只對第二位作了改變,不會影響到其它位,我們的目的也就達到了。

對於乙個操作,哪些許可權組能操作它,也可以用與運算來做,不讓某些許可權組有些操作的許可權,也可以先求補,再作與運算來解決。

3、許可權的驗證(與運算)

(userrolevalue & oprolevalue) != 0

對於某使用者,有沒有某操作的許可權,只要判斷它們兩個是不是屬於同乙個,或多個許可權組就可以了,所以用與運算就最合適不過了。

比如u1使用者,他的許可權值是5(文員組、經理組00000101),對於填寫操作的許可權值是00000011,說明對於文員組與主管組有填寫的許可權。

因為 00000101 & 00000011 == 1。對於乙個文員,他只屬於文員組,他的許可權值肯定是00000001了,對於提交操作00000110,因為00000101 &00000001 == 0,所以,他也就沒有提交操作的許可權了。

此的驗證方法,還可以用在選單許可權的驗證上來。許可權值還可以是binary資料型別的,此型別的位數可以很大,因此可以用作不分許可權組的情況。

演算法中二進位制運算的應用

def subset nums 通過二進位制數的特性,求給定集合的子集 param nums return n len nums res for i in range 2 n cur for j in range n if i 2 j 2 j return res def exchange x,y ...

二進位制許可權

package test 二進位制許可權使用 許可權 0 表示所有許可權 1 新增 0001 2 修改 0010 4 刪除 0100 8 檢視 1000 如 10 十進位制的 10 不是二進位制的 1 代表的許可權是 修改和檢視許可權 public class bitpermission 是否含有許...

巧妙運用二進位制驗證許可權

在許可權分配中有多個許可權級別,不同使用者分別有多個不同的許可權。論壇的許可權 檢視 發帖 投票 搜尋 使用者的許可權 使用者a 檢視 發帖 使用者b 檢視 使用者c 檢視 發帖 投票 搜尋 分析 有四種不同的許可權級別,總共2 4種許可權分配方式。像這樣許可權等級劃分和不同級別使用者的許可權分配採...