我不得不拆分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)));
}
}