使用按位比较与权限模型忽略第一位

Posted

技术标签:

【中文标题】使用按位比较与权限模型忽略第一位【英文标题】:Ignoring the first bit using bitwise compare with permission model 【发布时间】:2013-02-18 00:49:37 【问题描述】:

我有 101 和 110 位。我想使用一些按位运算符进行比较,忽略第一个位,例如 01 和 10。

例子:

I have:
101
110
===
01 & 10 <- How I want to consider
x00 <- The result I want

10110
11011
=====
0110 & 1011 <- How I want to consider
x0010 <- The result I want

如何在 java 中使用按位运算符实现这一点?

详情:

第一位始终为 1。 其他位是可变的。两个都 比较的两边将具有相同的位数。 我想检测如何在考虑其他位的情况下进行比较 忽略第一个。

用例:

我有 2 个权限值。第一个是 5/101(需要的权限),第二个是 6/110(用户拥有的权限)。 排除第一个块,它总是1,我想比较代表系统中某个权限规则的第三个块(按位)。 “所需权限”位掩码表示: 1 - 我用来考虑左侧填充零的始终固定值(除非有其他方法可以实现); 0 - 另一个对这个比较没用的权限规则(我们称之为权限 1); 1 - 当前权限规则所需的权限(我们称之为权限 2)。 “用户拥有的权限”是指: 1 - 要删除的固定值; 1 - 代表用户对权限1的值; 0 - 代表权限 2 的用户值。权限 2 的值为 1,但用户的值为 0,则不允许他执行所需的操作。允许执行相反的操作。

对于这种情况,任何更好的解决方案也将被视为正确答案。

【问题讨论】:

您需要固定位数,还是以某种方式可变? 它可以有任意数量的位,我只想考虑除第一个之外的所有其他位。 怎么知道位数?或者你想削减 either 数字的最高位?还是两个数的最高位相等是真的? @FagnerBrack 二进制数可以有任意位数。你必须更具体。 @GaborSch 这会使问题变得更加复杂,需要以 2 为底的对数或移位来确定打开的第一位。 【参考方案1】:

如果您知道有用位数(例如numofbits = 5),则表达式的位掩码为:

bitmask = (1 << numofbits) - 1

如果您不知道numofbits,只需使用num = num &gt;&gt; 1 进行循环,然后计算迭代直到您得到num == 0

对于用例:

result = (req_roles & user_roles) & (bitmask >> 1)

这只是ands 角色位,ans 削减了高位(始终为 1)


上一个问题的上一个答案:) :

如果您知道最大数字的位掩码(例如 bitmask = 0x1f11111 以位为单位)),那么您需要以下表达式的结果:

result = (a ^ b) ^ (bitmask >> 1)

它有什么作用?

比较所有位,相等的位为0 还原所有低位,因此相等的位将为 1(将高位排除在外,因此它将保持为 0)

【讨论】:

注意,这会起作用,但你需要知道有用的位数,否则答案会复杂得多。您可以通过对参数进行或运算并在循环中将其向右移动直到得到零来找到正在使用的第一位。计数比有用位数多一。【参考方案2】:

在比较它们之前,只需将参数与具有第一位关闭的掩码“和”,例如011 &amp; arg

编辑:在重述问题之后。

替代方法是使用基于角色的权限,这些权限比布尔权限字符串更灵活且更易于理解。他们也是自我记录的。很少使用基于位字符串的权限,除非内存或磁盘空间非常宝贵,例如 Unix 早在 80 年代初期或在嵌入式系统中开发时。

【讨论】:

你也可以只屏蔽比较的结果,这样屏蔽只应用一次。 好的,但是当使用按位进行比较时,我可以去掉第一位吗?如果我确实需要删除第一个位,使用“和”非常简单,但我想尝试这个而不会将位作为字符串弄乱。 不用把位搞乱成字符串,用布尔逻辑就好了。 你能用上面的例子给我一个sn-p吗?我想我没明白你的意思。 如果屏蔽结果,您将需要使用并使其为假或使其为真,这取决于您想要什么。【参考方案3】:

试试这个:

// tester 1
int x, y, z, mask;
x = 0x05; // 101
y = 0x06; // 110
mask = getMask(x, y);
z = (mask & (x & y));
System.out.println(String.format("mask: %x result: %x", mask, z));

// tester 2    
int x, y, z, mask;
x = 0x16; // 10110
y = 0x1B; // 11011
mask = getMask(x, y);
z = (mask & (x & y));
System.out.println(String.format("mask: %x result: %x", mask, z));

private int getMask(final int x, final int y) 
    int mask = findHighOrderOnBit(x, 0);
    mask = findHighOrderOnBit(y, mask) - 1;
    return mask;


private int findHighOrderOnBit(final int target, final int otherMask) 
    int result = 0x8000;
    for (int x = 0; x != 16; x++) 
        if ((result & target) > 0)
            break;
        result >>= 1;
    
    if (otherMask > result)
        result = otherMask;
    return result;

【讨论】:

@GaborSch - 这是一个示例 - 根据需要更改类型 - 根据需要添加错误检查等 您不需要调用 findHighOrderBit 两次,只需调用参数即可。 @PeterWooster - +1 - 很好的观察......我没想到。谢谢。

以上是关于使用按位比较与权限模型忽略第一位的主要内容,如果未能解决你的问题,请参考以下文章

linux用户权限

spring security acl 不比较按位权限

你知道权限管理的RBAC模型吗?

你知道权限管理的RBAC模型吗?

权限管理

权限管理模块设计