卧槽,提取信息,Java还有这个骚操作

2022年10月23日09:59:12 科技 1123

在本文中,我们来看看如何使用位操作符实现低级别的位掩码。我们将看到我们如何将一个单一的int变量作为一个单独的数据容器。

卧槽,提取信息,Java还有这个骚操作 - 天天要闻

位掩码

位掩码允许我们在一个数字变量中存储多个值。我们不再把这个变量看作一个整数,而是把它的每一个比特当作一个独立的值。

因为一个比特可以等于 0 或 1,我们也可以把它看成是 false 或 true 。我们也可以把一组比特切开,把它们当作一个较小的数字变量甚至是一个String

举个例子

假设我们有一个最小的内存空间,并且需要在一个int变量中存储所有关于用户账户的信息。前八位(来自32个可用位)将存储boolean信息,如 "该账户是否激活?"或 "该账户是否溢价?"

至于剩下的24位,我们将把它们转换成三个字符,作为用户的标识符。

编码

我们的用户将有一个标识符 "AAA",他将有一个活跃的高级账户(存储在前两个比特)。在二进制表示中,它将看起来像。

String stringRepresentation = "01000001010000010100000100000011";

使用内置的Integer#parseUnsignedInt方法,可以很容易地将其编码为一个int变量。

int intRepresentation = Integer.parseUnsignedInt(stringRepresentation, 2);
assertEquals(intRepresentation, 1094795523);

解码

这个过程也可以用 Integer#toBinaryString 方法来反转。

String binaryString = Integer.toBinaryString(intRepresentation);
String stringRepresentation = padWithZeros(binaryString);
assertEquals(stringRepresentation, "01000001010000010100000100000011");

提取一个比特

第一比特

如果我们想检查我们账户变量的第一位,我们只需要使用顺位 and 运算符和数字 1 作为掩码。因为数字 1在二进制形式中只有第一位被设置为1,其余的都是0,它将从我们的变量中删除所有的位,只留下第一个完整的位。

10000010100000101000001000000011
00000000000000000000000000000001
-------------------------------- &
00000000000000000000000000000001

然后我们需要检查产生的值是否不等于零。

intRepresentation & 1 != 0

任意位置的位

如果我们想检查其他的位,我们需要创建一个适当的掩码,这个掩码需要在给定的位置上有一个位设置为1,其余的设置为0。最简单的方法是对我们已有的掩码进行移位。

1 << (position - 1)

上面这行代码的位置变量设置为3,将把我们的掩码从 00000000000000000000000000000001 变成

00000000000000000000000000000100

因此,现在,比特方程将看起来像这样。

10000010100000101000001000000011
00000000000000000000000000000100
-------------------------------- &
00000000000000000000000000000000

把所有这些放在一起,我们可以写一个方法来提取给定位置上的单个比特。

private boolean extractValueAtPosition(int intRepresentation, int position) {
    return ((intRepresentation) & (1 << (position - 1))) != 0;
}

为了达到同样的效果,我们也可以将intRepresentation变量向相反方向移动,而不是改变掩码。

提取多个比特

我们可以用类似的方法从一个整数中提取多个比特。让我们提取我们的用户帐户变量的最后三个字节,并将其转换为一个字符串。首先,我们需要通过将变量向右移动来摆脱前八位的影响。

int lastThreeBites = intRepresentation >> 8;
String stringRepresentation = getStringRepresentation(lastThreeBites);
assertEquals(stringRepresentation, "00000000010000010100000101000001");

我们仍然有32位,因为int总是有32位。然而,现在我们只对前24位感兴趣,其余的都是零,会很容易被忽略。我们创建的int变量可以很容易地用作整数ID,但是因为我们想有一个字符串ID,所以我们还有一个步骤要做。

我们将把二进制的字符串表示法分成8个字符的组,把它们解析成char变量,然后把它们连接成一个最终的String

为了方便起见,我们还将忽略空字节。

Arrays.stream(stringRepresentation.split("(?<=\\G.{8})"))
  .filter(eightBits -> !eightBits.equals("00000000"))
  .map(eightBits -> (char)Integer.parseInt(eightBits, 2))
  .collect(StringBuilder::new, StringBuilder::append, StringBuilder::append)
  .toString();

应用一个比特掩码

我们也可以创建一个掩码来同时检查许多位,而不是提取和检查单个位的值。我们想检查我们的用户是否有一个活跃的高级账户,所以他的变量的前两个比特都设置为1。

我们可以用以前的方法分别检查它们,但创建一个掩码来选择它们,会更快。

int user = Integer.parseUnsignedInt("00000000010000010100000101000001", 2);
int mask = Integer.parseUnsignedInt("00000000000000000000000000000011", 2);
int masked = user & mask;

因为我们的用户有一个活跃的账户,但它不是高级账户,所以被屏蔽的值将只有第一个比特被设置为1。

assertEquals(getStringRepresentation(masked), "00000000000000000000000000000001");

现在,我们可以轻松而廉价地断言一个用户是否符合我们的条件。

assertFalse((user & mask) == mask);

总结

在本教程中,我们学习了如何使用位运算符来创建位掩码,并应用它

科技分类资讯推荐

如何让区块链技术更好赋能实体经济 - 天天要闻

如何让区块链技术更好赋能实体经济

区块链是数据共享和价值流通的重要基础设施,是下一代价值互联网络的核心技术。随着区块链技术在多场景积极落地,释放出显著的市场价值。实践证明,区块链只有深深扎根在具体应用场景中,才能够真正发挥出重要作用。在“十五五”期间,要更好推动区块链技术赋能实体经济,加快与场景融合发展。坚持系统性思维一方面,要用整...
通讯|中企助力尼日利亚水电枢纽重获新生 - 天天要闻

通讯|中企助力尼日利亚水电枢纽重获新生

新华社阿布贾6月10日电 通讯|中企助力尼日利亚水电枢纽重获新生 新华社记者杨喆 朱悦 在尼日利亚中北部尼日尔州新布萨以东约17公里,非洲第三长河尼日尔河流经卡因吉大坝,发出轰隆隆巨响,向下游倾泻而去。 这是2025年6月1日在尼日利亚尼日尔州拍摄的卡因吉水电站内的水电机组。新华社发(中国电建华东院公司供图) 坐落...
成都将上线预付式消费综合服务平台,这些行业和区域被纳入试点 - 天天要闻

成都将上线预付式消费综合服务平台,这些行业和区域被纳入试点

在日常生活中,预付式消费是一种常见的消费模式,例如美容美发卡、健身卡、培训课程预付费等。但是一些商家或机构的“跑路”事件,让行业发展面临信任危机,如何破解这一发展困境?6月13日,一场聚焦预付式消费健康发展的政企交流会,在成都市民营经济发展促进中心举办。本次活动主题为“惠企政策直达·预付生态共建”,主...
永久封禁!微信、快手连发公告 - 天天要闻

永久封禁!微信、快手连发公告

日前微信、快手宣布下架部分违规微短剧剧目对违规剧集相关发布账号永久封禁9日,微信珊瑚安全发布的《关于违规微短剧类小程序的处置公告(2025年6月)》指出:近期,平台通过巡查审核发现,部分微短剧存在不良价值观导向内容或存在侵权等行为。
生产过1亿台ThinkPad的工厂长什么样?京东采销618直播揭秘其品质密码 - 天天要闻

生产过1亿台ThinkPad的工厂长什么样?京东采销618直播揭秘其品质密码

京东618火热进行中,持续带给消费者更多惊喜。6月12日,京东笔记本采销团队携手知名硬件评测人“猪王”深入联想ThinkPad生产基地,全景呈现ThinkPad严苛的生产流程,更通过跌落测试等直观实验,验证了其军工级品质的可靠性。此外,京东笔记本采销团队为消费者带来多款热门产品的直播专享福利,更有十万红包雨发放,打造又好...
Bitget 向叙利亚用户敞开大门,提供全方位服务产品套件 - 天天要闻

Bitget 向叙利亚用户敞开大门,提供全方位服务产品套件

维多利亚,塞舌尔, June 13, 2025 (GLOBE NEWSWIRE) -- 领先的加密货币交易所和 Web3 公司 Bitget 现已为叙利亚公民提供该平台。 这在近期 OFAC 制裁暂停之后进行。 叙利亚公民和居民现在可以在该平台上注册、完成身份验证并获得全套服务,包括 P2P、现货交易、期货和获取收益的产品。 对于一个长期面临冲突、经济孤立和