Linux 操作系统的权限为什么是1,2,4 而不是 1,2,3?如何用二进制来做权限管理
来源:互联网 发布:java 方法签名是什么 编辑:程序博客网 时间:2024/05/17 06:31
1. 二进制做权限的优点
大家都知道,在Linux操作系统中,x - 可执行权限,w - 可写权限 , r - 可读权限。其权限值分别是1,2,4,但是有没有想过为什么是1,2,4 而不是 1,2,3 呢?
OK , 现在是不是发现 1,2,4 分别对应着2的幂次方(2^0、2^1 、2^2),在计算机中都是以二进制的方式进行存储,在计算时二进制的方式会更快。举个例子:如果一个人拥有读和写的权限,现在他的权限值为6,当需要判断他是否拥有写权限时,只需要用 6 和 2 进行按位与运算(6 & 2 = 2),结果非0 ,所以可以判断拥有此权限。当需要判断他是否拥有可执行权限时,同样只需要用 6 和 1 进行按位与运算 (6 & 1 = 0 ),结果为0,所以可以判断不拥有此权限。
6 & 2 = 2 00000110& 00000010——————---- 00000010 又或者:6 & 1 = 0 00000110& 00000001——————----- 00000000
为什么只需要用用户的权限值和对应的权限进行按位与运算就可以判断出是否拥有此权限呢??个人理解为:当每个2的幂次方分别代表一个权限时,刚好能够和对应的二进制位对应起来。当用户拥有此权限时,对应的权限值的二进制位会变为1,然后进行按位与运算,从而可以知道是否拥有此权限。
用二进制的方式除了可以加快速度,还有没有其他优点呢?如果在一个应用系统中,我们应该如何用二进制的方式来进行权限管理呢?
想要知道二进制的方式的优势就需要和一般方法进行比较,OK。
不采用二进制时数据表的设计:user - 用户表id name1 AA2 BB3 CCpermission表id name method/url1 查看帖子 get2 发布帖子 post3 修改帖子 update4 删除帖子 delete用户-权限对应表id uid perId1 1 12 1 3
采用二进制权限方法时数据表的设计:user - 用户表id name per_value1 AA 62 BB 73 CC 4permission表id name method/url value1 查看帖子 get 12 发布帖子 post 23 修改帖子 update 44 删除帖子 delete 8
从上面两张表的设计可以看出:采用二进制的方式少了一张中间表!!!它只多了两个字段:一个是权限对应的权限值,一个是用户拥有的权限值总和,所以可以知道——采用二进制的方式可以少一次表查询。
按照一般方式(不采用二进制的方式)的做法是:
获取当前请求的URL , 得到对应的权限对象(或 id)
查看当前用户是否含有此权限
采用二进制的方式:
获取当前请求的URL , 得到对应的权限对象(权限值),用户的权限值 & 当前权限的权限值
可以看出:采用二进制的方式少了一次表查询。
如果嫌每次请求都要去数据库中获取对应的权限对象太过于麻烦,则可以把全部的权限放入本地缓存中,因为每个请求都会进行判断,则可以视为热点数据,则可以放入本地缓存,从而减少数据库查询。这个时候:
不采用二进制的方式:
每次需要去用户-权限对应表中判断是否拥有相应的权限,嫌太麻烦,可以在user里面 用List<Integer> 装入所有自己拥有的权限id
采用二进制的方式:可以直接从本地缓存中取出权限值,然后可用户的权限值进行判断
由上列表可以看出:不管是从时间还是空间来说,二进制的方式都占有明显的优势!!
2. 如果用二进制做权限
现在,可以知道用二进制的方式来做权限拥有明显的优势,那么具体的运算应该是怎样的呢?
例子:用户AA含有权限值 15 , 当前权限值 81. 判断是否含有某个权限: 15 & 8 != 0 00001111& 00001000——————----- 000010002. 添加权限: 15 | 8 = 15 、 15 | 16 = 31 00001111 00001111| 00001000 00010000—————------- -——————--- 00001111 000111113. 删除某个权限 : 15 & (~8)= 7 00001111~ 11110111 ————------- 00000111
现在已经知道如何具体的进行运算,但是大家有没有一个问题:一个整型32bit 所对应的权限是有限的,那么应该怎么做呢??是用long吗??是个办法,但是这个能够一次性解决问题吗??有没有更好的办法呢??答案是有的。
结合分级索引,可以这样做:
可以看出:每个权限增加了一个权限位,用作分级,所以,现在唯一标识权限的可以用权限位和权限值来进行标识。那么这个时候:
public class User { private Integer userId; private String name; private String password;// 数组下标为0对应的值就为拥有权限位为0的权限值得总和 private long[] permissionSum;public boolean hasPermission(Permission permission){ int position = permission.getPosition(); long number = permission.getPermissionNum(); return !((permissionSum[position] & number) == 0); } }
- Linux 操作系统的权限为什么是1,2,4 而不是 1,2,3?如何用二进制来做权限管理
- 如何用不同的方式来处理安卓的权限管理?
- 干货|如何用开放性来做管理
- linux操作系统知识分享(3组、文件权限的管理4RPM管理)
- 如何用ASP实现权限的设置?
- Linux的权限管理
- linux的权限管理
- 权限管理二进制算法
- 二进制权限管理
- java 二进制 权限管理
- [教程]linux/UNIX操作系统文件系统权限管理
- 基于二进制的权限管理与验证
- 基于二进制的权限管理与验证
- 基于二进制的权限管理与验证
- 基于二进制的权限管理与验证
- 基于二进制的权限管理与验证
- 如何用命令行解决可执行文件的权限问题
- 如何用命令行解决可执行文件的权限…
- Android中收货地址管理Demo
- 最简单的白话讲解什么是面向切面(转)
- dubbo摘抄
- android应用开发-从设计到实现 4-3应用的创建与部署
- C++实现基数排序
- Linux 操作系统的权限为什么是1,2,4 而不是 1,2,3?如何用二进制来做权限管理
- 寻找使三个整数相加等于0的解
- [Java面试八]Hibernate总结以及在面试中的一些问题.
- 从勒索病毒看端口
- 关于String s是否默认初始化
- 如何获取手机信号
- 【Java】Java中的数据类型说明
- STM32中断优先级彻底讲解
- 程序设计模式(九) C++ 装饰(Decorator)模式