• 使用『与非』运算实现权限判断


    作者:广州 Stephen Cat
    初稿:2006 年 9 月 17 日 11:21 AM
    修订:2006 年 9 月 17 日 12:22 AM


    这种方法基于这样的数学原理:

    1)(2 | 4 | 16 | 32 | 256) & (4 | 32) == (4 | 32)

    2)Sigma ( 2n , n 是自然数 ) = 2n+1 - 1 ,即 1 + 2 + 4 + 8 + .... + 64 = 128 - 1 = 127

    这种方法的好处是存储形态简单,仅存储一个整型数值。

    代价是权限位的数量受语言的 Int 整数类型可处理位数的限制。即如果权限位的数量在 32 以下,就可以使用 Convert.ToInt32() 转换和存储;超过 32 位就要使用 Convert.ToInt64() 了;比 64 更多就没办法存储了。

    存取测试

    /// <summary>
    /// 烹饪材料
    /// </summary>
    public enum Stuff
    {
    水 
    = 1,
    米 
    = 2,
    皮蛋 
    = 4,
    姚柱 
    = 8,
    瘦肉 
    = 16,
    腊味 
    = 32,
    糯米 
    = 64,
    盐 
    = 128,
    味精 
    = 256,
    }

    /// <summary>
    /// 权限存储测试
    /// </summary>
    [Test]
    public void StorePermissionTest()
    {
        
    // 我有这些材料
        Stuff[] userStuffs = new Stuff[] {Stuff.水 , Stuff.米 , Stuff.瘦肉 , Stuff.腊味 , Stuff.盐 };

        Stuff stuffCollection 
    = (Stuff) 0;

        
    foreach(Stuff stuff in userStuffs)
        {
            stuffCollection 
    = stuffCollection | stuff;
        }

        
    // 通过『与』运算得到『我拥有什么材料』的数值封装
        Console.WriteLine(Convert.ToInt32(stuffCollection));
    }

    /// <summary>
    /// 权限校验测试
    /// </summary>
    /// <param name="userStuff">我拥有什么材料</param>
    /// <param name="cookbook">烹饪需要的材料</param>
    /// <returns>如果我拥有烹饪需要的全部材料,则返回 true;否则返回 false</returns>
    public bool isValid( Stuff userStuff, Stuff cookbook )
    {
        
    return (( userStuff & cookbook ) == cookbook);
    }

    /// <summary>
    /// 权限提取测试
    /// </summary>
    [Test]
    public void RestorePermissionsTest()
    {
        
    // 曾经通过『与』运算得到『我拥有什么材料』的数值封装
        int stuffs = 179;

        
    // 还原为材料枚举
        Stuff userStuff = (Stuff) stuffs;

        
    // 做白粥需要的材料
        Stuff congee = Stuff.水 | Stuff.米 | Stuff.盐 ;

        
    // 看来可以做白粥 哦 ^_^

        Console.WriteLine( 
    this.isValid(userStuff, congee) );

        
    // 做皮蛋瘦肉粥需要的材料
        Stuff congeePreservedEgg = Stuff.水 | Stuff.米 | Stuff.盐 | Stuff.皮蛋 | Stuff.瘦肉 ;

        
    // 看来不可以皮蛋瘦肉粥了 >_<

        Console.WriteLine( 
    this.isValid(userStuff, congeePreservedEgg) );
    }

    授权方式

            /// <summary>
            
    /// 添加权限测试
            
    /// </summary>
            public void AddPermissionTest()
            {
                
    // 曾经通过『与』运算得到『我拥有什么材料』的数值封装
                int stuffs = 179;

                
    // 还原为材料枚举
                Stuff userStuff = (Stuff) stuffs;

                Stuff addStuff 
    = Stuff.水 | Stuff.糯米 ;

                
    // 只加入了糯米
                userStuff = userStuff | addStuff ;

            }

            
    /// <summary>
            
    /// 丢弃权限测试
            
    /// </summary>
            public void RemovePermissionTest()
            {
                
    // 曾经通过『与』运算得到『我拥有什么材料』的数值封装
                int stuffs = 179;

                
    // 还原为材料枚举
                Stuff userStuff = (Stuff) stuffs;

                Stuff dropStuff 
    = Stuff.水 | Stuff.盐 | Stuff.糯米 ;

                
    // 丢弃了水和盐
                userStuff =  userStuff ^ (dropStuff & userStuff );

            }

    系统权限更新后用户权限更新的方式

    1. 系统删除或添加某种权限后,在权限修改记录表中存储以下权限修正操作信息:对权限的操作类型(移除、添加)、权限值、执行日期时间

    2. 用户信息表中记录最后更新权限的日期时间

    3. 用户登入系统时,从权限修改记录表中获取自上次用户更新权限至今需要执行的权限修正操作,依次完成权限修正后把权限值持久化回系统,同时在用户信息表中记录本次更新权限的日期时间(如果没有要执行的权限修正操作,则忽略这两步)

  • 相关阅读:
    Java基础教程
    一个RDBMS左连接SQL执行计划解析
    hive时间日期函数及典型场景应用
    ETL数据采集方法
    数据仓库保存历史数据方法之拉链表
    NAS服务器局域网内IPad、手机、电视盒子等联网播放
    转:主流数据恢复软件——EasyRecovery/Ashampoo Undeleter/Wise Data Recovery/Recuva/Undelete 360
    [转]office2010一直卡在“正在受保护的视图中打开”
    [转]PROE传动链条的装配教程
    linux下svn定时更新项目
  • 原文地址:https://www.cnblogs.com/HeroBeast/p/1061281.html
Copyright © 2020-2023  润新知