使用二进制权限控制

/*
引言:
    使用二进制权限控制,可以减少程序的逻辑判断,如有50 种权限需要验证,
  一般会写 if...else if...else if 或 if(n==1 || n==2 || ... n=50 )
  这种写法。
    如果使用二进制权限控制,则可使用一个if即可验证 if((权限码|n)==n),
  注意 n 必须为 2的幂级。
    c#中标记[System.Flags]特性的枚举,实质上是就是这种鉴权方式。
    [System.Flags]
    public enum Role
    { 
        read = 1,  //001
        write = 2,  //010
        delete= 4,  //100
    }
  使用建议:权限被频繁验证,权限值多于32个
定义:
  授权码:权限值的集合表示
  授权值:单个权限值,该值必须为2的幂级数,取值范围 2^0 到 2^62 
  授权:“权限码”=“权限”组每项进行“或”操作)
  回收:待收回的“权限”取反后,和“授权码”进行“与”操作
  鉴权:有两个公式:“权限”=“授权码”&“权限”;“授权码”=“授权码”|“权限”;
  
1.权限值
  long类型可表示的2的最大幂级数为:4611686018427387904
  转为二进制数表示为:10000000...000(共63位;一个1,六十二个0;表示为2^62)
  加上2^0=1 ,所以1个long最多可以表示 63 个状态,2^0 到 2^62 次方;
  实例:  
  bin name 授权码
  0001 添加 (1)
  0010 修改 (2)
  0100 删除 (4)
  1000 查看 (8)
  
  0011 表示:添加 + 修改 权限
  1011 表示:查看 + 修改 + 添加 权限
  
2.授权(“权限码”=“权限”组每项进行“或”操作)


  授予 (添加 + 修改) 权限
  0011 = 0001 | 0010 
  0011 => 3
  3=1|2
  
  select bin(3),bin(1),bin(2),bin(1|2);
  
  授予 (查看 + 修改 + 添加) 权限
  1011 = 0001 | 0010 | 1000
  1011 => 11 #转为十进制数
  11= 1|2|8  #十进制数运算      
  
  select bin(11),bin(1),bin(2),bin(8),bin(1|2|8);
  
3.回收权限(待收回的“权限”取反后,和“授权码”进行“与”操作)
  公式:code = code&(~num)
  
  1>A =(查看 + 修改 + 添加) 组合
  1011 = 0001 | 0010 | 1000
  11= 1|2|8  #十进制数运算    
  
  2>回收 A 的"添加"权限
  1010 = 1011 & (~0001)
  1010 => 10 = 11&(~1)
  
  select bin(11&(~1)),11&(~1);
  
4.鉴权
  公式1:num = code & num; (“权限”=“授权码”&“权限”)
  公式2:code = code | num; (“授权码”=“授权码”|“权限”)
  注:“权限” 必须为 2 的幂级数,否则会出错。
    
  1>A =(查看 + 修改 + 添加) 组合
  1011 = 0001 | 0010 | 1000
  11= 1|2|8  #十进制数运算    
  
  2>鉴权
  
  鉴权1
  select 11&4; #与 4 等于 0,无权限
  select 11&8; #与 8 等于 8,有权限  
  
  鉴权2
  select 11|4; #或 4 不等于 11,无权限  
  select 11|8; #或 8 等于 11,有权限  
  
5.错误鉴权值,及非2的幂级,实例


  错误鉴权1
  select 11&3; #与 3 等于 3,错误
  select 11&9; #与 9 等于 9,错误
  
  错误鉴权2
  select 11|3; #或 3 等于 11,错误
  select 11|9; #或 9 等于 11,错误
  


*/
SELECT POWER(2,0),POWER(2,1),POWER(2,2),POWER(2,64);
SELECT BIN(1),BIN(~1),BIN(POWER(2,50));


#菜单表
SELECT * FROM `wdt_base_menu`;


#权限表
SELECT * FROM `wdt_base_authority`;


#角色表
SELECT * FROM `wdt_base_role`;


#角色授权表
SELECT * FROM `wdt_base_roleauthority`;






#查询角色包含的菜单
SELECT * 
FROM `wdt_base_menu` 
WHERE Authoritys&16383=Authoritys AND module=1;