C# 使用位操作符实现简单的权限操作

在Linux下对文件或者目录赋权限的时候其实就是使用了位运算来对一个State标志位进行操作。

因为在二进制中0001,0010,0100,1000,等以此类推,这几个数字进行按位于或者按位或操作的话会有一些神奇的事情发生。

常见的位运算主要是,与&、或|、非~这三种,这三种运算符的特性跟逻辑操作服差不多,1是true,0是false而已,只不过这里运算规则是这种:

  • 1 & 0 = 0
  • 1| 0 = 1
  • ~1 = 0

首先我们来建立一个枚举如下:

[Flags]
public enum TestEnum
{
    Insert = 1,
    Delete = 2,
    Query = 4,
    Update = 8
}

这里的[Flags]特性的作用是让被修饰的枚举支持位运算操作,而每个枚举的值我们使用2的n次方进行赋值,那么这里就表示为了:

  • 0001
  • 0010
  • 0100
  • 1000

然后这里的二进制位每一位1代表有某种权限,0则代表没有,例如0011则说明拥有Insert与Delete两种权限。那么我们根据位运算的法则,如果要让一个State标志位拥有两种权限,则只需要将其进行或运算即可,例如0001 | 0010 = 0011,换成代码来说如下:

TestEnum permissions = TestEnum.Insert | TestEnum.Delete;
// 简化写法
TestEnum permissions |= TestEnum.Delete;

// 删除权限则进行与非,或者异或操作均可实现
permissions &= ~TestEnum.Delete;
// 0011 & (~0010->1101) = 0001 -> Insert

而当我们需要进行判断一个State是否拥有某种权限的时候,则需要将其与需要判断的权限进行按位于运算,如果得到的结果等于要判断的权限,则说明这个State拥有这个权限值。

TestEnum permissions = TestEnum.Insert | TestEnum.Delete;
if((permissions & TestEnum.Insert) == TestEnum.Insert)
{
    Console.WriteLine("拥有插入权限!");
}

// 0011 & 0001 = 0001