C# 使用二进制 逻辑(与、或、非)位移运算 控制系统权限
来源:互联网 发布:java去掉字母和数字 编辑:程序博客网 时间:2024/06/05 17:58
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Grass.Authorize{ /// <summary> /// 二进制授权帮助类,最多支持 62 种不同权限,鉴权值最大为2的62次方(即:4611686018427387904) /// </summary> public class BinAuth { /// <summary> /// 验证非负正整数是否为2的幂级 /// </summary> /// <remarks></remarks> /// <param name="n"></param> /// <returns></returns> public static bool IsBinPower(long n) { /* 判断是2的幂,1个数乘以2就是将该数左移1位,而2的0次幂为1, 所以2的n次幂(就是2的0次幂n次乘以2)就是将1左移n位, 这样我们知道如果一个数n是2的幂,则其只有首位为1, 其后若干个0,必然有n & (n - 1)为0。(在求1个数的二进制表示中1的个数的时候说过 ,n&(n-1)去掉n的最后一个1)。因此,判断一个数n是否为2的幂,只需要判断n&(n-1)是否为0即可。 */ return (n & (n - 1)) == 0; } /// <summary> /// 获取2 的 x 次方值 /// </summary> /// <param name="x">x 次方值</param> /// <returns></returns> public static long GetBinPower(int x) { return (long)System.Math.Pow(2, x); } /// <summary> /// 将数值转为等值2进制数 /// </summary> /// <param name="n"></param> /// <returns></returns> public static string GetBin(long n) { return Convert.ToString(n, 2); } /// <summary> /// 生成鉴权码 /// </summary> /// <param name="arr">权限值(2的幂级)</param> /// <remarks>每个鉴权值执行或操作(code = code | n)</remarks> /// <returns></returns> public static long GenAuthCode(params long[] arr) { if (arr == null) throw new Exception("权限值数组不允许为空,Grass.BinAuth.GenAuthCode()"); long code = 0; arr.ToList().ForEach(x => { if (!IsBinPower(x)) throw new Exception(string.Format("值 {0} 为无效的鉴权码不是2的幂级", x)); if (x< 0 ||x > 4611686018427387904) throw new Exception(string.Format("鉴权值 {0} 应大于 0 小于 4611686018427387904", x)); code = code | x; }); return code; } /// <summary> /// 添加权限 /// </summary> /// <param name="authCode">鉴权码</param> /// <param name="auth">权限值(2的幂级)</param> /// <remarks>code = authCode | auth</remarks> /// <returns></returns> public static long AddAuth(long authCode,long auth) { if (!IsBinPower(auth)) throw new Exception(string.Format("值 {0} 为无效的鉴权码不是2的幂级", auth)); if (auth < 0 || auth > 4611686018427387904) throw new Exception(string.Format("鉴权值 {0} 应大于 0 小于 4611686018427387904", auth)); long code = authCode | auth; return code; } /// <summary> /// 移除权限 /// </summary> /// <param name="authCode">鉴权码</param> /// <param name="auth">权限值(2的幂级)</param> /// <remarks>code = authCode & (~auth)</remarks> /// <returns></returns> public static long RemoveAuth(long authCode, long auth) { if (!IsBinPower(auth)) throw new Exception(string.Format("值 {0} 为无效的鉴权码不是2的幂级", auth)); if (auth < 0 || auth > 4611686018427387904) throw new Exception(string.Format("鉴权值 {0} 应大于 0 小于 4611686018427387904", auth)); long code = authCode & (~auth); return code; } /// <summary> /// 验证权限 /// </summary> /// <param name="authCode">鉴权码</param> /// <param name="auth">权限值(2的幂级)</param> /// <remarks>auth == (authCode & auth)</remarks> /// <returns></returns> public static bool IsHasAuth(long authCode, long auth) { if (!IsBinPower(auth)) throw new Exception(string.Format("值 {0} 为无效的鉴权码不是2的幂级", auth)); if (authCode <= 0 || auth<=0) return false; return auth == (authCode & auth); } }}
using System;using System.Collections.Generic;using System.Linq;using System.Text;using Grass.Authorize;using Microsoft.VisualStudio.TestTools.UnitTesting;namespace TestGrass{ [TestClass] public class TestBinAuth { /// <summary> /// 验证非负正整数是否为 2 的幂级 /// </summary> /// <remarks> /// 判断是2的幂,1个数乘以2就是将该数左移1位,而2的0次幂为1, 所以2的n次幂(就是2的0次幂n次乘以2)就是将1左移n位, 这样我们知道如果一个数n是2的幂,则其只有首位为1,其后若干个0,必然有n & (n - 1)为0。(在求1个数的二进制表示中1的个数的时候说过,n&(n-1)去掉n的最后一个1)。因此,判断一个数n是否为2的幂,只需要判断n&(n-1)是否为0即可。 /// </remarks> /// <returns></returns> [TestMethod] public void TestIsBinPower() { string str = ""; for (int i = 0; i < 64; i++) { long n = BinAuth.GetBinPower(i); str = BinAuth.GetBin(n); if (!BinAuth.IsBinPower(n)) Assert.IsTrue(false); } Assert.IsTrue(true); } /// <summary> /// 获取2 的 x 次方值 /// </summary> /// <returns></returns> [TestMethod] public void TestGetBinPower() { long n = (long)Math.Pow(2, 50); string ns = BinAuth.GetBin(n); long m = BinAuth.GetBinPower(50); string ms = BinAuth.GetBin(m); Assert.IsTrue(n == m); } /// <summary> /// 将数值转为等值2进制数 /// </summary> /// <returns></returns> [TestMethod] public void TestGetBin() { long n = (long)Math.Pow(2, 50); string s1 = BinAuth.GetBin(n); string s2 = Convert.ToString(n, 2); Assert.IsTrue(s1.Equals(s2)); } /// <summary> /// 生成鉴权码 /// </summary> /// <param name="arr">权限值(2的幂级)</param> /// <remarks>每个鉴权值执行或操作</remarks> /// <returns></returns> [TestMethod] public void TestGenAuthCode() { long authCode = 0; string binStr = ""; List<long> codeList = new List<long>(); for (int i = 1; i <= 62; i++) { codeList.Add((long)Math.Pow(2, i)); } authCode = BinAuth.GenAuthCode(codeList.ToArray()); binStr = BinAuth.GetBin(authCode); ; Assert.IsTrue(true); } /// <summary> /// 添加权限 /// </summary> /// <remarks>code = authCode | auth</remarks> /// <returns></returns> [TestMethod] public void TestAddAuth() { long authCode = 0; string binStr = ""; for (int i = 1; i <= 62; i++) { long x = BinAuth.GetBinPower(i); authCode = BinAuth.AddAuth(authCode, x); binStr = BinAuth.GetBin(authCode); } binStr = BinAuth.GetBin(authCode); Assert.IsTrue(true); } /// <summary> /// 移除权限 /// </summary> /// <remarks>code = authCode & (~auth)</remarks> /// <returns></returns> [TestMethod] public void TestRemoveAuth() { long authCode = 9223372036854775806;//表示最大权限值 string binStr = ""; for (int i = 1; i <= 62; i++) { long x = BinAuth.GetBinPower(i); authCode = BinAuth.RemoveAuth(authCode, x); binStr = BinAuth.GetBin(authCode); } binStr = BinAuth.GetBin(authCode); Assert.IsTrue(true); } /// <summary> /// 验证权限 /// </summary> /// <returns></returns> [TestMethod] public void TestIsHasAuth() { long[] arr = {1, 2, 4, 8, 16, 32, 64}; long authCode = BinAuth.GenAuthCode(arr); Assert.IsTrue(BinAuth.IsHasAuth(authCode, 1)); Assert.IsTrue(BinAuth.IsHasAuth(authCode, 2)); Assert.IsTrue(BinAuth.IsHasAuth(authCode, 4)); Assert.IsTrue(BinAuth.IsHasAuth(authCode, 8)); Assert.IsTrue(BinAuth.IsHasAuth(authCode, 16)); Assert.IsTrue(BinAuth.IsHasAuth(authCode, 32)); Assert.IsTrue(BinAuth.IsHasAuth(authCode, 64)); Assert.IsFalse(BinAuth.IsHasAuth(-1, 0)); Assert.IsFalse(BinAuth.IsHasAuth(0, 0)); Assert.IsFalse(BinAuth.IsHasAuth(authCode, 128)); Assert.IsFalse(BinAuth.IsHasAuth(authCode, 256)); } }}
0 0
- C# 使用二进制 逻辑(与、或、非)位移运算 控制系统权限
- JavaScript之逻辑与、或、非运算
- sql位运算符【&(位与)、~(位非)、|(位或)、^(位异或)】与位移
- JavaSE005_二进制转换、与或非异或、位运算
- Java的运算符号(逻辑与、或、非、移位运算)
- Java的运算符号(逻辑与、或、非、移位运算)
- java 的与& ,或| ,非~ 运算符计算方法逻辑
- 单层感知器就能够实现 逻辑与运算、逻辑或运算和逻辑非运算,不能实现逻辑异或运算
- 逻辑运算(逻辑非,逻辑与,逻辑或,逻辑异或)
- Java 位运算(移位、位与、或、异或、非) 以及负数的二进制相互计算
- leetcode算法题1: 两个二进制数有多少位不相同?异或、位移、与运算的主场
- oracle中逻辑与、逻辑或、逻辑与非函数的使用
- 逻辑与或非优先级
- js逻辑与或非
- 逻辑与和逻辑或运算符
- “逻辑和”与 “逻辑或”运算符
- C#位移运算符
- C#位移运算符
- log4j 日志服务器_项目实际使用日记
- 可以让你少奋斗十年的工作经验(转)
- avaya dhcp option
- 鱼眼镜头的分类
- vs2008使用gsoap调用WeatherWS
- C# 使用二进制 逻辑(与、或、非)位移运算 控制系统权限
- 多线程显示进度条,子线程耗时10s,主线程在这10s中不停的刷新、显示,进度条界面。
- VLSI test 复习所得
- struts2文件下载
- Xcode6下学习autolayout 一
- Windows8下PhoneGap 4 + Android Studio 1.0 + VS2013配置指南
- 使用LINQ读取分隔符文本文件
- 使用angularjs 编辑数组
- vim、gvim在windows下中文乱码的终极解决方案