字节数组(byte[])实现二进制串的循环移位

版权声明:本文为博主原创文章,未经博主允许不得转载。有问题联系[email protected] https://blog.csdn.net/weixin_40411846/article/details/79580431

字节数组(byte[])实现二进制串的循环移位

最近去公司实习了。公司的主业是网络安全,先说一个:密码学中的移位都是循环移位。现在用字节数组byte[]存储二进制串,1024个二进制数字就是128个字节,byte[128],如何实现这样的二进制串的循环移位呢?
网上只有对数组的移位,比如int[],char[],string,但直接套用byte[]是不符合要求的!我自己感觉这套东西是我全网首发哈哈哈哈哈哈哈哈哈哈哈!(因为我自己已经翻来覆去百度过很久了哈哈哈哈哈哈)
感谢徐利军老师提供的算法框架和王啸赟同学的提点。已通过手算验证!


算法核心Java代码如下:(屏蔽掉的代码就是原本出问题的地方,大家注意右移运算中补1/0的问题)
【2018年3月16日17:25:08】原来的算法前的判断逻辑一直隐约觉得不对,今天算了一下午改正了bug,现在全部放上来……

import java.util.Arrays;

public class Byte_SHIFT {   //循环移位

    public static void main(String[] arg) { //测试
        byte[] test = new byte[128];
        test[0] = 0;
        for (int i = 1; i < 128; i++) {
            test[i] = 1;
        }
        System.out.println(Arrays.toString(test));
        test = leftShift(test, 250);
        System.out.println(Arrays.toString(test));
    }

    public static byte[] hexStringToByte(String hex) {
        int len = (hex.length() / 2);
        byte[] result = new byte[len];
        char[] achar = hex.toCharArray();
        for (int i = 0; i < len; i++) {
            int pos = i * 2;
            result[i] = (byte) (toByte(achar[pos]) << 4 | toByte(achar[pos + 1]));
        }
        return result;
    }

    private static int toByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    private static void RotateRightOne(byte[] bytes) {
        byte valBit;
        valBit = (byte) (bytes[bytes.length - 1] << (byte) (7));
        for (int i = bytes.length - 1; i > 0; i--) {
            bytes[i] = (byte) ((bytes[i] >> (byte) (1)) | (bytes[i - 1] << (byte) (7)));
        }
        bytes[0] = (byte) ((bytes[0] >> (byte) (1)) | valBit);
    }

    public static byte[] rightShift(byte[] bytes, int X) {  //X<bytes.length
        int byte_move;
        int binary_move;
        if (X % 1024 == 0) {
            return bytes;
        } else {
            if (X > 1024) {
                while (X > 1024) {
                    X -= 1024;
                }
            }
            byte_move = (X - X % 8) / 8;
            byte[] new_bytes = new byte[128];
            System.arraycopy(bytes, 0, new_bytes, byte_move, bytes.length - byte_move);
            System.arraycopy(bytes, bytes.length - byte_move, new_bytes, 0, byte_move);
            binary_move = X % 8;
            if (binary_move == 0) {
                return new_bytes;
            } else {
                cyclic_right_shift(new_bytes, binary_move);
                return new_bytes;
            }
        }
    }

    public static byte[] leftShift(byte[] bytes, int X) {  //X<bytes.length
        int byte_move;
        int binary_move;
        if (X % 1024 == 0) {
            return bytes;
        } else {
            if (X > 1024) {
                while (X > 1024) {
                    X -= 1024;
                }
            }
            byte_move = (X - X % 8) / 8;
            byte[] new_bytes = new byte[128];
            System.arraycopy(bytes, byte_move, new_bytes, 0, bytes.length - byte_move);
            System.arraycopy(bytes, 0, new_bytes, bytes.length - byte_move, byte_move);
            binary_move = X % 8;
            if (binary_move == 0) {
                return new_bytes;
            } else {
                cyclic_left_shift(new_bytes, binary_move);
                return new_bytes;
            }
        }
    }

    private static void cyclic_left_shift(byte[] bytes, int X) {
/*        byte first_byte_begin_bit = (byte) (bytes[0] >> (byte) (8 - X));
        if (first_byte_begin_bit < 0) {
            byte temp = (byte) ((byte) (-128) >> (byte) (8 - X - 1));
            first_byte_begin_bit = (byte) (first_byte_begin_bit ^ temp);
        }
        for (int i = 0; i < bytes.length - 1; i++) {
            byte A = (byte) (bytes[i] << (byte) (X));
            byte B = (byte) (bytes[i + 1] >> (byte) (8 - X));
            if (B < 0) {
                byte temp = (byte) ((byte) (-128) >> (byte) (8 - X - 1));
                B = (byte) (B ^ temp);
            }
            bytes[i] = (byte) (A | B);
        }
        byte A = (byte) (bytes[bytes.length - 1] << (byte) (X));
        bytes[bytes.length - 1] = (byte) (A | first_byte_begin_bit);*/
        int first_byte_begin_bit =  bytes[0] >>> 8 - X;
        for (int i = 0; i <bytes.length-1; i++)
        {
            int A=(bytes[i]&0xff)<<  X;
            int B=bytes[i + 1] >>> (8 - X);
            bytes[i] = (byte) (A|B);
        }
        bytes[bytes.length-1]=(byte)((bytes[bytes.length-1]&0xff)<<X);
        bytes[bytes.length-1] = (byte)(bytes[bytes.length-1]|first_byte_begin_bit);
    }

    private static void cyclic_right_shift(byte[] bytes, int X) {
/*        byte end_byte_final_bit = (byte) (bytes[bytes.length - 1] << (byte) (8 - X));
        for (int i = bytes.length - 1; i > 0; i--) {
            byte A = (byte) (bytes[i] >> (byte) (X));
            byte B = (byte) (bytes[i - 1] << (byte) (8 - X));
            if (A < 0) {
                byte temp = (byte) ((byte) (-128) >> (byte) (X - 1));
                A = (byte) (A ^ temp);
            }
            bytes[i] = (byte) (A | B);
//            bytes[i] = (byte) ((byte) ((bytes[i] >> (byte) (X))) | (byte) ((bytes[i - 1] << (byte) (8 - X))));
        }
        byte A = (byte) (bytes[0] >> (byte) (X));
        if (A < 0) {
            byte temp = (byte) ((byte) (-128) >> (byte) (X - 1));
            A = (byte) (A ^ temp);
        }
        bytes[0] = (byte) (A | end_byte_final_bit);*/
        //bytes[0] = (byte) ((byte) ((bytes[0] >> (byte) (X))) | end_byte_final_bit);
        int end_byte_end_bit =  bytes[bytes.length - 1] << 8 - X;
        for (int i = bytes.length - 1; i > 0; i--)
        {
            int A=(bytes[i]&0xff)>>>  X;
            int B=bytes[i - 1] << 8 - X;
            bytes[i] = (byte) (A|B);
        }
        bytes[0]=(byte)((bytes[0]&0xff)>>>X);
        bytes[0] = (byte)(bytes[0]|end_byte_end_bit);
    }
}
         

猜你喜欢

转载自blog.csdn.net/weixin_40411846/article/details/79580431