拆分IP八位字节

时间:2017-05-22 14:17:23

标签: java ip byte

我不得不拆分IP地址字节并将它们保存在树中。这就是我实施的内容,但我感觉有更快的方法来实现同一目标。如果您有任何想法,请告诉我:))

private static final int MAX_IP_BITS_SIZE = 16 * Byte.SIZE;

/**
 * Splits octet bytes in new byte array based on the splitter size.
 *
 * @param bytes address representation of IPv4 or IPv6 to be split.
 * @param splitSize is the amount of bit to split on. It could be from 1 to 7, otherwise returns unsplit bytes.
 * @return byte[] split version of the address bytes.
 */
private byte[] splitAddressBytes(byte[] bytes, final int splitSize)
{
    if (splitSize < 1 || splitSize > 7)
    {
        return bytes;
    }

    int byteIndex = 0;
    int changeByteIndex = 0;
    byte[] octetBytes = new byte[MAX_IP_BITS_SIZE];

    for (int i = 0; i < Byte.SIZE * bytes.length; i++)
    {
        /*
         * Get byte index based on the splitter size, e.g. if the splitter size is 3, which mean that 'i % Byte.SIZE / splitSize' will
         * vary from 0 to 2, i.e. on each change between those value means we can move to the next index.
         */
        int inputBitIndex = i % Byte.SIZE;
        if (changeByteIndex != inputBitIndex / splitSize)
        {
            changeByteIndex = inputBitIndex / splitSize;
            byteIndex++;
        }

        /*
         * Traverse all bits one by one and check if it is set to 1, if so add it to the result byte. Get the bit at the position
         * "i / Byte.SIZE", then shift each bit at the first position and check if it is 1 or 0, i.e. i % Byte.SIZE is the position of
         * the bit that we want to check (0,1,2,3,4,5,6,7), e.g. 128 is 1000 0000 and i % Byte.SIZE when i=0 is 0, as and i % Byte.SIZE
         * is 0, then do not shift, just AND 1000 0000 and 0x80 (which is 128 or 1000 0000). In that case the result is 128, which is
         * not 0 so the bit at that position is 1. Second attempt i=1, so i / Byte.SIZE = 0 and i % Byte.SIZE = 1. In that case we want
         * to check second bit which is 1000 0000 << 1 = 0000 0000, from where 0000 0000 & 1000 0000 = 0, so the bit at that position is
         * 0.
         */
        if ((bytes[i / Byte.SIZE] << inputBitIndex & 0x80) != 0)
        {
            /*
             * Now when we know that bit at that position (i) is set to 1 we have to place it to the particular byte at the desired
             * position based on the splitter size, i.e. 'octetBytes[byteIndex] & 0xFF' - get current value of the bit based on the
             * index (which also take into account split size) and apply bitwise OR with the bit that is set to 1 based on the bit
             * shift. So to determine the index position of the bit: '(Byte.SIZE - splitSize)' - get offset or the starting point from
             * the byte based on the splitter size. 'inputBitIndex % splitSize' - get which bit has to be set to 1, i.e. in case of
             * splitter set to 3 the block size is 3 and that will result in 0,1, or 2. '(Byte.SIZE - splitSize) + (inputBitIndex %
             * splitSize))' - combining offset and bit position we have the final bit position where we have to place the bit with value
             * 1. So with bit shift of 0x80 at that position, e.g. 1000 0000 >>> 5 = 0000 0100 we have the desired byte to add to
             * already existing. e.g. current byte is 0000 0000 and we want to add 1 at the correct position, 0000 0000 | 0x80 (which is
             * 128 or 1000 0000) >>> 5, where 5 is the bit position from 5 trough 7 in case of splitter size 3. e.g. 0000 0000 | 0000
             * 0100 = 0000 0100.
             */
            octetBytes[byteIndex] = (byte)(octetBytes[byteIndex] & 0xFF | (0x80 >>> (Byte.SIZE - splitSize) + (inputBitIndex % splitSize)));
        }
    }

0 个答案:

没有答案