【问题标题】:How to shift bits across array of ints如何在整数数组中移动位
【发布时间】:2013-11-18 15:39:45
【问题描述】:

好的,我会保持简单明了。

我正在使用 Java 进行 SHA-256 的粗略实现,为了使类方法有利于应用程序中的其他类,我决定将数据作为 32 位整数数组进行 I/O (整数)。显然,这些类型的使用在很大程度上依赖于位运算符的使用,那么我如何在一个整数数组中完成按位移位,如下所示:

给定一个数据数组,假设:

 int[16] data;

其中前 14 个整数值的数据用 0x0000000 填充,用于对话,但分别填充最低的两个:

 data[14] = 0x12345678;
 data[15] = 0x01ABCDEF;

如何实现左移,如果左移两个,

 data[13] = 0x00000012;
 data[14] = 0x34567801;
 data[15] = 0xABCDEF00;

有人有什么想法吗?

【问题讨论】:

  • 当你移位时,也在下一个 int 的正确位中进行 OR。例如,data[15] = (data[15] << 2) | (data[14] >>> 30)
  • 也许使用 BigInteger 并创建一个 API“以保持类方法有利于应用程序中的其他类”。 BigInteger 有类似shiftLeft(int n) 的方法,见docs.oracle.com/javase/7/docs/api/java/math/BigInteger.html
  • @RonE - 是否可以从 int 数组构造 BigInteger 实例? Oracle 文献仅提供使用字节数组的示例。 32 位和 8 位特性在构建过程中是否会有所不同?
  • @blasthash 如果您以 int[16] 形式接收数据,则编写一个将其转换为 byte[64] 的方法
  • 或者像我说的那样转移它们。这并不难。

标签: java int bit-manipulation shift sha256


【解决方案1】:

1) 编写一个帮助方法将您的int[16] data 转换为byte[64] bytedata

2) 使用构造函数BigInteger(byte[] val) 创建一个BigInteger

3) 使用shiftLeft(int n)shiftRight(int n) 进行位移

4) 编写一个辅助方法将您的byte[64] bytedata 转换回int[16] data。见byte array to Int Array here

BigInteger 中其他有用的方法包括clearBit(int n)setBit(int n)flipBit(int n)testBit(int n)

【讨论】:

    【解决方案2】:

    按位左移:

    `x << n` is the same as `x *= 2^n`  
    

    查看溢出位 (MSB): x / (2^32) &gt;= 1 //因为我们使用的是 32 位整数


    同样,按位右移:

    `x >> n` is the same as `x /= 2^n`  
    

    查看溢出位 (LSB): x % 2

    通过添加或减去设置值将溢出位附加到相邻的 int。你真的应该像我在评论中提到的那样使用 BigInteger,其他任何事情都需要你自己读取和附加在数组位置之间移动的位的实现。

    【讨论】:

    • 是否可以从 BigInteger '下转换'回 int 数组?如果你读过算法,我正在实现的阶段是 padding 阶段,其中任意数量的位被附加到值的末尾以建立 512 位的数字。不过,算法中的大多数其他处理是通过数组中特定 32 位段与常量或函数的 直接 关系,所以我希望能够保持这种容量的易用性.
    • 我可以通过右移 32,然后返回 32 来截断和划分 32 位来做到这一点,但这是一种迂回且低效的方法。
    • @blasthash 是的,使用toByteArray() 并编写一个辅助函数来转换为 int 数组。 Java 是关于层和链接的,使用模块化的部分来实现你的目标。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-24
    • 2014-10-25
    • 2023-03-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多