16位左右旋转用于Java

时间:2014-06-05 12:38:15

标签: java bit-manipulation

我试图在Java中搜索左旋圆形和圆形旋转16位数据(不是8位数据)但是大多数圆形旋转我可以找到处理8位数据。如何在Java中左右执行16位圆形旋转?感谢。

以下是我当前不起作用的代码:

public byte[] rotr(byte[] input, int shift) {
    int output = (binToInt(input) << shift) | (binToInt(input) >> (16 - shift));
    return BigInteger.valueOf(output).toByteArray();
}

public int binToInt(byte[] b) {
    return new BigInteger(b).intValue();
}

public String byteToHex(byte b) {
    char hexDigit[] = {
        '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'
    };
    char[] array = {hexDigit[(b >> 4) & 0x0f], hexDigit[b & 0x0f]};
    return new String(array);
}

public String byteArrayToHex(byte[] bytes) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < bytes.length; i++) {
        sb.append(byteToHex((byte) bytes[i]));
    }
    return sb.toString();
}

public static void main(String[] args) {
    byte[] out = rotr(new byte[] {(byte) 0x97, (byte) 0xA1}, 7);
    System.out.println(byteArrayToHex(out));
}

十六进制(0x97A1)位字符串:1001011110100001

尝试rotr-7:11001011;

例外位字符串:1101000011001011(0xD0CB)

1 个答案:

答案 0 :(得分:0)

通过将数据放入字节数组,您确实在努力实现自己的目标。这使得很难判断您的问题是在转换中还是在轮换中。

旋转本身非常简单:

 public static int ror16(int data, int distance) {
     distance &= 15; // limit rotation to distance mod 16
     data &= 0xFFFF; // ensure only the lower 16 bits can be set
     return (data >> distance) | (data << (16 - distance));
 }

请注意,当向右移动int(假设保持16位)时,您需要确保高16位真的为零,否则您将转移垃圾。

您的问题很可能源于从byte []到int的转换。构造函数BigInteger(byte [])将假定值为 signed ,因此转换为int时,BigInteger会为您提供0xFFFF97A1。因为你没有考虑设置的高位,所以这会使你的轮换加速。

编辑:删除所有byte [] fluff,只使用更合理的int来处理16位值:

public static main(String[] argv) {
    int result = ror16(0x97A1, 7) & 0xFFFF;
    System.out.println(Integer.toHexString(result));
}