我正在处理分区特定IP地址范围的问题(在Java中)。假设我有:
startIP endIP
1.2.3.4 1.2.5.6
我需要将此范围缩小到每个[0,255]间隔,所以我们有:
startIP endIP
1.2.3.4 1.2.3.255
1.2.4.0 1.2.4.255
1.2.5.0 1.2.5.6
我正在或多或少地考虑这个问题,例如为from 7 to 26
分区小数范围,我们有[7, 9], [10, 19], [20, 26]
。唯一的区别是我们正在处理256-simal
个数字。任何想法,伙计们?谢谢!
答案 0 :(得分:2)
您可以使用InetAddress
进行此操作,并运行一个简单的循环来执行增量:
InetAddress from = InetAddress.getByName("1.2.3.4");
InetAddress to = InetAddress.getByName("1.2.5.6");
byte[] partsTo = to.getAddress();
for (;;) {
System.out.print(from+" - ");
byte[] parts = from.getAddress();
boolean sameUpperPart = true;
for (int i = 0 ; sameUpperPart && i < parts.length-1 ; i++) {
sameUpperPart &= (partsTo[i] == parts[i]);
}
if (sameUpperPart) {
System.out.println(to);
break;
}
int last = parts.length-1;
parts[last] = (byte)0xFF;
System.out.println(InetAddress.getByAddress(parts));
parts[last] = 0x00;
for (int i = last-1 ; i >= 0 ; i--) {
if (++parts[i] != 0) {
break;
}
}
from = InetAddress.getByAddress(parts);
}
此代码produces the following output on ideone:
/1.2.3.4 - /1.2.3.255
/1.2.4.0 - /1.2.4.255
/1.2.5.0 - /1.2.5.6
答案 1 :(得分:1)
我不知道Java的具体解决方案,但是C中有一个算法。它会将IP范围划分为最大可能的子网并打印它们。结果范围将在子网边界上对齐。
#define NETWORK_ZEROS(ip, prefix) ((ip) & (0xffffffff << (32 - (prefix))))
#define NETWORK_ONES(ip, prefix) ((ip) | (~ (0xffffffff << (32 - (prefix)))))
void print_ip(unsigned long ip)
{
unsigned char bytes[4];
bytes[0] = ip & 0xFF;
bytes[1] = (ip >> 8) & 0xFF;
bytes[2] = (ip >> 16) & 0xFF;
bytes[3] = (ip >> 24) & 0xFF;
printf("%d.%d.%d.%d", bytes[3], bytes[2], bytes[1], bytes[0]);
}
void partition_ip(unsigned long start, unsigned long stop)
{
int i;
while (start < stop)
{
// Change the start of the loop to 24 if you
// need to align on /24 boundaries
for (i=0; i <= 32; i++)
{
if (NETWORK_ZEROS(start, i) == start &&
NETWORK_ONES(start, i) <= stop)
{
print_ip(NETWORK_ZEROS(start, i));
printf(" - ");
print_ip(NETWORK_ONES(start, i));
printf("\n");
start = NETWORK_ONES(start, i) + 1;
break;
}
}
}
}
要将IP转换为二进制数,请执行以下操作
a.b.c.d => ((((a*256)+b)*256)+c)*256+d
或
ip = (a << 24) | (b << 16) | (c << 8) | d
如果您希望通过利用位移来提高效率。
答案 2 :(得分:1)
首先将IP地址转换为单个整数,然后重复添加256,然后转换回IP地址进行分区。
public class IPPartition {
public static void main(String[] args) {
String startIP = "1.2.3.4";
String endIP = "1.2.5.6";
long start = toLong(startIP);
long end = toLong(endIP);
long last = start;
long part = (start / 256 + 1) * 256;
for (; part < end; last = part, part += 256) {
System.out.println(toIP(last) + " " + toIP(part));
}
System.out.println(toIP(last) + " " + toIP(end));
}
private static long toLong(String ip) {
String[] tokens = ip.split("\\.");
long sum = 0;
for (int i = 0; i < 4; i++) {
sum *= 256;
sum += Integer.parseInt(tokens[i]);
}
return sum;
}
private static String toIP(long num) {
String result = "";
for (int i = 0; i < 4; i++) {
long section = num % 256;
result = section + result;
if (i < 3) result = "." + result;
num /= 256;
}
return result;
}
}
我在这里使用longs只是为了安全,但你可以使用整数,我没有尝试过。还有一些错误或其他问题,我还没有彻底测试过。
答案 3 :(得分:1)
一些示例代码(假设初始转换为int []在外部完成)并且实际上并不返回有用数据(只是打印)。但这个想法就在那里。
public class Convertor {
public static void convert(int []a, int []b) {
int left = (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3];
int right = left | 0xff;
int end = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3];
while ( right < end ) {
System.out.printf("%s -> %s\n", toIp(left), toIp(right));
left = right + 1; right += 256;
}
System.out.printf("%s -> %s\n", toIp(left), toIp(end));
}
private static String toIp(int value) {
return String.format("%d.%d.%d.%d",
value >> 24 & 0xFF,
value >> 16 & 0xFF,
value >> 8 & 0xFF,
value & 0xFF);
}
}
致电网站:
Convertor.convert(new int[]{1, 2, 3, 4}, new int[]{1, 2, 5, 6});
输出:
1.2.3.4 -> 1.2.3.255
1.2.4.0 -> 1.2.4.255
1.2.5.0 -> 1.2.5.6