最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 权限管理竟然还能用二进制判断,太好用了(一) - 掘金

    正文概述 掘金(小小切图仔_可笑可笑)   2021-09-26   642

    小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

    最近跟我们公司后台做一个项目,发现了一个好玩的东西哈,真的以前没想到的,也有可能是我们太笨了,哈哈哈哈。不过现在用到也不晚,可能是老技术了,我也不知道,知道的人可以跟我说一下,是不是以前的人都是这样用的。

    那这个是什么技术呢!!!它就是利用进制位运算来做用户的权限管理。非常好用,下面我分三个议题来讲。

    1. javaScript的进制位运算
    2. 权限的判断
    3. 用后感

    一· 进制的位运算

    我在用这个位运算的时候也是绞尽脑汁想了一天,最后发现使用的方法很简单,因为js已经帮你集成好了用法,这让我们用起来会更加方便。我是那种用一种技术就必须搞明白原理的人,不然不清不楚用一种技术,后期定位问题也很难,所以希望大家也是一样的。位运算我脑补了很多资料,看了很多博客的资料。

    废话不多说,直接整起。。。。

    1. JavaScript 位运算

    1.1. Number

    在讲位运算之前,首先简单看下 JavaScript 中的 Number,下文需要用到。

    JavaScript 里,数字均为基于 IEEE 754 标准的双精度 64 位的浮点数,引用某乎的图片,它的结构长这样:

    权限管理竟然还能用二进制判断,太好用了(一) - 掘金

    sign bit(符号): 用来表示正负号

    exponent(指数): 用来表示次方数

    mantissa(尾数): 用来表示精确度

    也就是说一个数字的范围只能在 -(2^53 -1) 至 2^53 -1 之间。

    在此之外还有四种数字进制,有些进制是我们与计算机沟通的最终形态:

    四种数字进制分别为:十进制、十六进制、八进制、二进制。

    • 十进制:没有前导0的数值。这个也是我们经常用到
    • 八进制:有前缀0o0O的数值,或者有前导0、且只用到0-7的八个阿拉伯数字的数值。
    • 十六进制:有前缀0x0X的数值。
    • 二进制:有前缀0b0B的数值。

    下面是一些例子。

    // 十进制
     
    123456789
     
    0
     
     
    // 二进制:前缀 0b,0B
     
    0b10000000000000000000000000000000 // 2147483648
     
    0b01111111100000000000000000000000 // 2139095040
     
    0B00000000011111111111111111111111 // 8388607
     
     
    // 八进制:前缀 0o,0O(以前支持前缀 0)
     
    0o755 // 493
     
    0o644 // 420
     
     
    // 十六进制:前缀 0x,0X
     
    0xFFFFFFFFFFFFFFFFF // 295147905179352830000
     
    0x123456789ABCDEF // 81985529216486900
     
    0XA // 10
    

    我们 JavaScriptNumber 就讲这么多。想了解更多的可以去看百度维基百科

    1.2. 位运算

    w3c是这么解释javasCript 位运算的:

    简单来说就是:按位操作符将其操作数当作 32 位的比特序列(由 0 和 1 组成)操作,返回值依然是标准的 JavaScript 数值。

    JavaScript 中位运算操作符有

    运算符用法描述
    按位与(AND)a & b对于每一个比特位,只有两个操作数相应的比特位都是 1 时,结果才为 1,否则为 0。按位或(OR)a | b对于每一个比特位,当两个操作数相应的比特位至少有一个 1 时,结果为 1,否则为 0。按位异或(XOR)a ^ b对于每一个比特位,当两个操作数相应的比特位有且只有一个 1 时,结果为 1,否则为 0。按位非(NOT)~a反转操作数的比特位,即 0 变成 1,1 变成 0。左移(Left shift)a << b将 a 的二进制形式向左移 b (< 32) 比特位,右边用 0 填充。有符号右移a >> b将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位。无符号右移a >>> b将 a 的二进制表示向右移 b (< 32) 位,丢弃被移出的位,并使用 0 在左侧填充。

    下面通过一些实例来加深对位运算的理解。

    1.2.1 按位与(&)

    &&运算符我们都知道,只有两个都为真,结果才为真。&道理是一样的,只有两个数的值为1时,才返回1。例如1和3的按位与操作:

    				    0001
    				 &  0011
    				---------
    				    0001
    

    只有对应的数为1时,结果才为1,其他都为0。
    判断一个数是奇数还是偶数,我们会用求余数来判断:

    function assert(n) { 
        if (n % 2 === 1) { 
            console.log("n是奇数"); 
        } else { 
            console.log("n是偶数"); 
        } 
    }
    assert(3); // "n是奇数"
    

    我们也可以用一个数和1进行按位&操作来判断,而且速度更快:

    function assert(n) { 
        if (n & 1) { 
            console.log("n是奇数");
        } else {
            console.log("n是偶数"); 
        } 
    }
    assert(3); // "n是奇数"
    

    下面是位运算过程:

    				 1 = 0001
    				 3 = 0011
    				 --------
    			         & = 0001
    

    奇数的二进制码的最后一位数肯定是1,而1只有最后一位为1,按位&操作之后,结果肯定只有最后一位数为1。而偶数的二进制表示的最后一位数是0,和1进行按位&操作,结果所有位数都为0。

    1.2.2 按位或(|)

    |与||操作符的道理也是一样的,只要两个数中有一个数为1,结果就为1,其他则为0。

                                       0001 
                                     | 0011
                                  ---------
                                       0011
    

    对浮点数向下求整,我们会用下面的方法:

    var num = Math.floor(1.1); // 1
    

    我们也可以用位运算来求整:

    var num = 1.1 | 0; // 1
    

    其实浮点数是不支持位运算的,所以会先把1.1转成整数1再进行位运算,就好像是对浮点数向下求整。所以1|0的结果就是1。

    1.2.3 按位非(~)

    按位非就是求二进制的反码:

    var num = 1; // 二进制 00000000000000000000000000000001 
    var num1 = ~num; // 二进制 11111111111111111111111111111110
    

    我们知道,js中的数字默认是有符号的。有符号的32位二进制的最高位也就是第一位数字代表着正负,1代表负数,0代表整数。那到底11111111111111111111111111111110等于多少呢?最高位为1代表负数,负数的二进制转化为十进制:符号位不变,其他位取反加1。取反之后为10000000000000000000000000000001,加1之后为10000000000000000000000000000010,十进制为-2。

    1.2.4 按位异或(^)

    按位异或是两个数中只有一个1时返回1,其他情况返回0。

                              0001 
                            ^ 0011 
                         --------- 
                              0010
    

    数字与数字本身按位异或操作得到的是0,因为每两个对应的数字都相同,所以最后返回的都是0。

    我们经常会需要调换两个数字的值:

    var num1 = 1, num2 = 2, temp; 
    temp = num1;
    num1 = num2; // 2 
    num2 = temp; // 1
    

    如果装逼一点的话,可以这样:

    var num1 = 1, num2 = 2;
    num1 = [num2, num2 = num1][0];
    console.log(num1); // 2
    console.log(num2); // 1
    

    如果想再装的稳一点的话,可以这样:

    var num1 = 1, num2 = 2; 
    num1 ^= num2; // num1 = num1 ^ num2 = 1 ^ 2 = 3
    num2 ^= num1; // num2 = num2 ^ (num1 ^ num2) = 2 ^ (1 ^ 2) = 1 
    num1 ^= num2; // num1 = num1 ^ num2 = 3 ^ 1 = 2
    console.log(num1); // 2 
    console.log(num2); // 1
    

    结束但又没有完全结束

    东西有点多,这一篇我们暂时先说到这里,还没结束,下一篇我们会继续讲。感兴趣的小伙伴可以留意一下。

    创作不易,请多多支持,点点赞、点点关注与收藏,就是对我最大的支持,感谢观看我的文章,这里是小小切图仔_可笑可笑


    起源地下载网 » 权限管理竟然还能用二进制判断,太好用了(一) - 掘金

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元