Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/307.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Util将字节数组中的位提取到新字节[]_Java_Arrays_Bit Manipulation_Offset - Fatal编程技术网

Java Util将字节数组中的位提取到新字节[]

Java Util将字节数组中的位提取到新字节[],java,arrays,bit-manipulation,offset,Java,Arrays,Bit Manipulation,Offset,我正在尝试构建一个实用程序类,以使按位操作和转换更具可读性。目前,我一直在构建一种从字节数组中提取位并从中形成新字节[]的方法。不用说,我对逐位运算不是很熟练 我相信这可能是通过使用位集实现的,但是会有太多的转换,而且实现会是Java特定的。如果有一个清晰的算法,以后可以很容易地移植到其他语言,那就太好了 到目前为止,我已经做到了: public static byte[]toBytes(int offset/*full bytes*/,int bitsofset/*bytes+bits*/,i

我正在尝试构建一个实用程序类,以使按位操作和转换更具可读性。目前,我一直在构建一种从字节数组中提取位并从中形成新字节[]的方法。不用说,我对逐位运算不是很熟练

我相信这可能是通过使用位集实现的,但是会有太多的转换,而且实现会是Java特定的。如果有一个清晰的算法,以后可以很容易地移植到其他语言,那就太好了

到目前为止,我已经做到了:

public static byte[]toBytes(int offset/*full bytes*/,int bitsofset/*bytes+bits*/,int bitscont,byte…bytes){
int字节计数=比特计数/8;
int paddingBits=bitsCount%8;
int partialBits=8-填充位;
如果(填充位>0){
字节计数++;
}
字节[]数据=新字节[字节计数];
返回数据;
}
我已将上述内容注释掉,并将其替换为临时内容

public static byte[]toBytes(int offset,int bitsofset,int bitscont,byte…bytes){
int firstBitIndex=(偏移量*8)+比特集;
返回新的BigInteger(新的BigInteger(1,字节).toString(2).substring(firstBitIndex,firstBitIndex+BitScont),2.toByteArray();
}
然而,我仍然希望有一个适当的实现,尽可能少的开销,并且不特定于Java(没有使用Java特定的工具,比如BitSet)

这是我期望它做什么的一个暗示

/**
*[0000 0110 1111 0010]=单位(1,4,12[xxxx xxxx xxxx 0110 1111 0010 xxxx xxxx])
*[0000 0110 1111 0010]=单位(1,5,12[xxxx xxxx xxxx X0111 1001 0xxx xxxx])
*[0000 0110 1111 0010]=单位(1,6,12[xxxx xxxx xxxx XXXX01 1011 1100 10xx xxxx])
*/
下面是一些单元测试

公共类ByteUtilTest{
@试验
公共无效toBytes_sameByte(){
byte[]result=ByteUtil.toBytes(1,4,3,
toByte(“11111111”),
toByte(“11110111”),
toByte(“11111111”),
托拜特(“11111111”);
资产质量(toBinaryString(toByte(“00000011”)),toBinaryString(result));
}
@试验
公共无效toBytes_sameByte_full(){
byte[]result=ByteUtil.toBytes(1,0,8,
toByte(“11111111”),
toByte(“0111011”),
toByte(“11111111”),
托拜特(“11111111”);
资产质量(toBinaryString(toByte(“0111011”)),toBinaryString(result));
}
@试验
不带偏移量()的公共无效到字节{
byte[]result=ByteUtil.toBytes(1,0,0,
toByte(“11111111”),
toByte(“0111011”),
toByte(“11111111”),
托拜特(“11111111”);
assertEquals(0,结果长度);
}
@试验
公共无效toBytes\u sameByte\u noneWithOffset(){
byte[]result=ByteUtil.toBytes(1,3,0,
toByte(“11111111”),
toByte(“0111011”),
toByte(“11111111”),
托拜特(“11111111”);
assertEquals(0,结果长度);
}
@试验
public void toBytes\u twoBytes\u resulttwithtwobytes(){
byte[]result=ByteUtil.toBytes(1,2,11,
toByte(“11111111”),
toByte(“0111011”),
toByte(“10011111”),
托拜特(“11111111”);
资产质量(toBinaryString(toByte(“00000110”)、toByte(“10110011”)、toBinaryString(result));
}
@试验
public void toBytes\u twoBytes\u resulttwithonebyte(){
byte[]result=ByteUtil.toBytes(1,2,7,
toByte(“11111111”),
toByte(“0111011”),
toByte(“10011111”),
托拜特(“11111111”);
资产质量(toBinaryString(toByte(“011011”)),toBinaryString(result));
}
@试验
public void toBytes\u twoBytes\u firstFull(){
byte[]result=ByteUtil.toBytes(1,0,11,
toByte(“11111111”),
toByte(“0111011”),
toByte(“10011111”),
托拜特(“11111111”);
资产质量(toBinaryString(toByte(“00000011”)、toByte(“10101100”)、toBinaryString(result));
}
@试验
public void toBytes\u twoBytes\u lastFull(){
byte[]result=ByteUtil.toBytes(1,5,11,
toByte(“11111111”),
toByte(“0111011”),
toByte(“10011101”),
托拜特(“11111111”);
资产质量(toBinaryString(toByte(“00000101”)、toByte(“10011101”)、toBinaryString(result));
}
@试验
public void toBytes\u twoBytes\u bothFull(){
byte[]result=ByteUtil.toBytes(1,0,16,
toByte(“11111111”),
toByte(“0111011”),
toByte(“10011101”),
托拜特(“11111111”);
资产质量(toBinaryString(toByte(“0111011”)、toByte(“10011101”)、toBinaryString(result));
}
@试验
public void toBytes_三字节(){
byte[]result=ByteUtil.toBytes(1,2,19,
toByte(“11111111”),
toByte(“0111011”),
toByte(“10011101”),
托拜特(“10111111”);
资产质量(
toBinaryString(
toByte(“00000110”),
toByte(“10110011”),
toByte(“10110111”),
toBinaryString(结果));
}
@试验
public void toBytes\u 3bytes\u firstFull(){
byte[]result=ByteUtil.toBytes(1,0,19,
toByte(“11111111”),
toByte(“0111011”),
toByte(“10011101”),
托拜特(“10111111”);
资产质量(
toBinaryString(
toByte(“00000011”),
toByte(“10101100”),
toByte(“11101101”),
public static byte[] bitSubstring(int byteOffset, int bitOffset,
                                  int lengthInBits, byte... source) {
    return bitSubstring(8 * byteOffset + bitOffset, lengthInBits, source);
}
public static byte[] bitSubstring(int startBit, int lengthInBits,
                                  byte... source) {
    assert startBit >= 0 && startBit < 8 * source.length;
    assert lengthInBits >= 0 && startBit + lengthInBits <= 8 * source.length;

    int lengthInBytes = (int) Math.ceil(lengthInBits / 8.0);
    byte[] target = new byte[lengthInBytes];
    int startByte = startBit / 8;
    int endBitExclusive = startBit + lengthInBits;
    int endByteExclusive = (int) Math.ceil(endBitExclusive / 8.0);
    int sourceBytesToRead = endByteExclusive - startByte;
    int lowerPartSize = 8 * endByteExclusive - endBitExclusive;
    int shiftLowerUp = (8 - lowerPartSize);
    int shiftUpperDown = lowerPartSize;
    int lastSrc = 0;
    if (sourceBytesToRead > lengthInBytes) {
        lastSrc = source[startByte] & 0xFF;
        startByte++;
    }
    for (int targetByte = 0; targetByte < target.length; ++targetByte) {
        int curSrc = source[startByte + targetByte] & 0xFF;
        target[targetByte] |= (lastSrc << shiftLowerUp)
                            | (curSrc >>> shiftUpperDown);
        lastSrc = curSrc;
    }
    int overhang = 8 * lengthInBytes - lengthInBits;
    if (overhang > 0) {
        target[0] &= 0xFF >>> overhang;
    }
    return target;
}
public static byte[] bitSubstringSlow(int startBitSource, int lengthInBits,
                                      byte... source) {
    byte[] target = new byte[(int) Math.ceil(lengthInBits / 8.0)];
    int startBitTarget = (8 - lengthInBits % 8) % 8;
    for (int i = 0; i < lengthInBits; ++i) {
        setBit(target, startBitTarget + i, getBit(source, startBitSource + i));
    }
    return target;
}

public static int getBit(byte[] source, int bitIdx) {
    return (source[bitIdx / 8] >>> (7 - bitIdx % 8)) & 1;
}

public static void setBit(byte[] target, int bitIdx, int bitValue) {
    int block = bitIdx / 8;
    int shift = 7 - bitIdx % 8;
    target[block] &= ~(1 << shift);
    target[block] |= bitValue << shift;
}
public static byte[] bitSubstringSlow2(int startBitSource, int lengthInBits,
                                       byte... source) {
    byte[] target = new byte[(int) Math.ceil(lengthInBits / 8.0)];
    int startBitTarget = (8 - lengthInBits % 8) % 8;
    for (int i = 0; i < lengthInBits; ++i) {
        int srcIdx = startBitSource + i;
        int tgtIdx = startBitTarget + i;
        target[tgtIdx / 8] |= ((source[srcIdx / 8] >>> (7 - srcIdx % 8)) & 1)
                              << (7 - tgtIdx % 8);
    }
    return target;
}