C#中的位操作

    技术2025-01-17  8

       比较基础的东西,平时用的不多,真到碰到时却不会用了,下面是整理的一些资料  int类型即Int32, 由4个字节32位表示,高第31位(编号从零开始)用来表示正负,1为负数,0为正数 (左表示高位,右表示低)  int 类型的负数是采用补码来表示的,即在对应的int类型正数上按位求反后再加1  比方计算-1,其正数为 0000000...001(31个零跟一个1) 那么按位求反后应该是 111111111....10 ,再加1的结果是11111111...111(32个1).  long类型跟int类似,只不过long由8字节64位表示    数据转换常用代码 //将16进制数0XFFFFFFFF转换为整数(Int32) MessageBox.Show( Convert.ToInt32("FFFFFFFF", 16).ToString()); //显示 -1 //将2进制数11111111转换为整数(Int32),注意11111111 等效于 0000...00011111111 (前面24个零) MessageBox.Show(Convert.ToInt32("11111111",2).ToString());// 显示 255 //将整数-1转换成2进制字符串 MessageBox.Show(Convert.ToString(-1, 2)); // -1的二进制表示,显示11111....11 (32个1) //将整数-1转换成16进制字符串 MessageBox.Show(Convert.ToString(-1, 16)); // -1的16进制表示,显示FFFFFFFF  使用BitConverter    byte[] bytes = new byte[] { 0xFF, 0xFF, 0xFF, 0xFF,0 ,0};    //取bytes数据的第0个到第3个元素(int类型有4个字节) ,转化成整数    MessageBox.Show( BitConverter.ToInt32(bytes, 0).ToString()); //显示 -1;   //将byte[] 数组表示成十六进制字符串序列,各元素转化后用 "-"连接,顺序不变    MessageBox.Show( BitConverter.ToString(bytes)); //显示 FF-FF-FF-FF-0-0  //获取10(Int32)的字节数组  byte[] arr=BitConverter.GetBytes(10); //生成的数组为 {10,0,0,0}   MessageBox.Show(BintConverter.ToString(arr)); //显示为0A-0-0-0;  这里注意10的Int32内存表示方法是 00-00-00-0A(高字节左边低字节在右边) ,而上面的是通过BinConverter转化后是高字节在右边低字节在左边.    使用位操作  在开发一些带权限控制的功能时我们有可能用到位操作,  比方系统中有一些资源,每个资源对应一组操作,假设有8种操作  这个时候你就可以设计这么一张表 资源用户操作表(用户名,资源号,操作类型) 一些数据:              tools  1, 1              tools  2, 2              tools  1 , 3              alsve  3, 1              alsve  1,2

      在上面我们用数字1~8表示8种操作,显然如果一个用户对某一资源拥有全部权限的话就需要8条记录来表示,如果用户达到几十万级别时这个表的数据量将会很庞大.  改用位来表示操作  资源用户操作表(用户名,资源号,操作数)  这里我们使用了操作数,他是int类型的整数 我们使用其低8位来表示某用户对某资源拥有操作,对应位为1则表示有相应权限,为零则表示没有.  在上面的规则下我们需要用到以下操作  1.判断某一位是否为1 即用户是否拥有某资源的某一操作,   bool表达式  (操作数 & (1<< 位置)) > 0;  2.设置某一位为1,即将某一资源的某一操作分配给用户  操作数=操作数 | (1< <位置);>  3. 设置某一位为0,即将用户对某一资源的某一操作取消  操作数=操作数 &  (~(1< <位置)); 移位后,按位求反,再与操作数做与操作 一些实现细节  用户登录后一次性将用户的资源操作数据加载到 Hashtable里(包括用户属于的角色分配的资源操作数据) 代码类似如下: foreach(...){  hash.Add("资源号","操作数") ; }  当然用户会属于一些角色的,而给角色分配的资源操作可能跟给用户分配的资源操作重叠,  这个时候就需要将2者合并, 修改后的代码类似如下 foreach(....){             if (hash.ContainsKey("资源号"))             {                 hash["资源号"] = (int)hash["资源号"] | "操作数";             }             else             {                 hash.Add("资源号", "操作数");             } }   Hashtable可以方便的序列化,序列化后的数据可以保存在 Session(使用SQL保存Session)或者保存在加密的ViewState里面,当然同样可以把ViewState保存到SQL服务器里,不过,使用SQL Session 比较方便      

    最新回复(0)