java java中如何从ip地址获取子网
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14994934/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
how to get subnet from ip address in java
提问by William
I get the ip(ipv4,such as 192.168.161.125),how can I get the subnet in which my pc is? java method and String format result is prefered.
我得到了ip(ipv4,例如192.168.161.125),我怎样才能得到我的电脑所在的子网?java方法和字符串格式的结果是首选。
subnet is network which is calculated using ip address and subnet mask
子网是使用IP地址和子网掩码计算的网络
Thanks.
谢谢。
回答by Nidhish Krishnan
This is how you would do it in Java,
这就是你在 Java 中的做法,
import java.util.ArrayList;
import java.util.List;
public class IPv4 {
int baseIPnumeric;
int netmaskNumeric;
public IPv4(String symbolicIP, String netmask) throws NumberFormatException {
/* IP */
String[] st = symbolicIP.split("\.");
if (st.length != 4)
throw new NumberFormatException("Invalid IP address: " + symbolicIP);
int i = 24;
baseIPnumeric = 0;
for (int n = 0; n < st.length; n++) {
int value = Integer.parseInt(st[n]);
if (value != (value & 0xff)) {
throw new NumberFormatException("Invalid IP address: "+ symbolicIP);
}
baseIPnumeric += value << i;
i -= 8;
}
/* Netmask */
st = netmask.split("\.");
if (st.length != 4)
throw new NumberFormatException("Invalid netmask address: "
+ netmask);
i = 24;
netmaskNumeric = 0;
if (Integer.parseInt(st[0]) < 255) {
throw new NumberFormatException(
"The first byte of netmask can not be less than 255");
}
for (int n = 0; n < st.length; n++) {
int value = Integer.parseInt(st[n]);
if (value != (value & 0xff)) {
throw new NumberFormatException("Invalid netmask address: " + netmask);
}
netmaskNumeric += value << i;
i -= 8;
}
/*
* see if there are zeroes inside netmask, like: 1111111101111 This is
* illegal, throw exception if encountered. Netmask should always have
* only ones, then only zeroes, like: 11111111110000
*/
boolean encounteredOne = false;
int ourMaskBitPattern = 1;
for (i = 0; i < 32; i++) {
if ((netmaskNumeric & ourMaskBitPattern) != 0) {
encounteredOne = true; // the bit is 1
} else { // the bit is 0
if (encounteredOne == true)
throw new NumberFormatException("Invalid netmask: " + netmask + " (bit " + (i + 1) + ")");
}
ourMaskBitPattern = ourMaskBitPattern << 1;
}
}
/**
* Specify IP in CIDR format like: new IPv4("10.1.0.25/16");
*
*@param IPinCIDRFormat
*/
public IPv4(String IPinCIDRFormat) throws NumberFormatException {
String[] st = IPinCIDRFormat.split("\/");
if (st.length != 2)
throw new NumberFormatException("Invalid CIDR format '"
+ IPinCIDRFormat + "', should be: xx.xx.xx.xx/xx");
String symbolicIP = st[0];
String symbolicCIDR = st[1];
Integer numericCIDR = new Integer(symbolicCIDR);
if (numericCIDR > 32)
throw new NumberFormatException("CIDR can not be greater than 32");
/* IP */
st = symbolicIP.split("\.");
if (st.length != 4)
throw new NumberFormatException("Invalid IP address: " + symbolicIP);
int i = 24;
baseIPnumeric = 0;
for (int n = 0; n < st.length; n++) {
int value = Integer.parseInt(st[n]);
if (value != (value & 0xff)) {
throw new NumberFormatException("Invalid IP address: " + symbolicIP);
}
baseIPnumeric += value << i;
i -= 8;
}
/* netmask from CIDR */
if (numericCIDR < 8)
throw new NumberFormatException("Netmask CIDR can not be less than 8");
netmaskNumeric = 0xffffffff;
netmaskNumeric = netmaskNumeric << (32 - numericCIDR);
}
/**
* Get the IP in symbolic form, i.e. xxx.xxx.xxx.xxx
*
*@return
*/
public String getIP() {
return convertNumericIpToSymbolic(baseIPnumeric);
}
private String convertNumericIpToSymbolic(Integer ip) {
StringBuffer sb = new StringBuffer(15);
for (int shift = 24; shift > 0; shift -= 8) {
// process 3 bytes, from high order byte down.
sb.append(Integer.toString((ip >>> shift) & 0xff));
sb.append('.');
}
sb.append(Integer.toString(ip & 0xff));
return sb.toString();
}
/**
* Get the net mask in symbolic form, i.e. xxx.xxx.xxx.xxx
*
*@return
*/
public String getNetmask() {
StringBuffer sb = new StringBuffer(15);
for (int shift = 24; shift > 0; shift -= 8) {
// process 3 bytes, from high order byte down.
sb.append(Integer.toString((netmaskNumeric >>> shift) & 0xff));
sb.append('.');
}
sb.append(Integer.toString(netmaskNumeric & 0xff));
return sb.toString();
}
/**
* Get the IP and netmask in CIDR form, i.e. xxx.xxx.xxx.xxx/xx
*
*@return
*/
public String getCIDR() {
int i;
for (i = 0; i < 32; i++) {
if ((netmaskNumeric << i) == 0)
break;
}
return convertNumericIpToSymbolic(baseIPnumeric & netmaskNumeric) + "/" + i;
}
/**
* Get an arry of all the IP addresses available for the IP and netmask/CIDR
* given at initialization
*
*@return
*/
public List<String> getAvailableIPs(Integer numberofIPs) {
ArrayList<String> result = new ArrayList<String>();
int numberOfBits;
for (numberOfBits = 0; numberOfBits < 32; numberOfBits++) {
if ((netmaskNumeric << numberOfBits) == 0)
break;
}
Integer numberOfIPs = 0;
for (int n = 0; n < (32 - numberOfBits); n++) {
numberOfIPs = numberOfIPs << 1;
numberOfIPs = numberOfIPs | 0x01;
}
Integer baseIP = baseIPnumeric & netmaskNumeric;
for (int i = 1; i < (numberOfIPs) && i < numberofIPs; i++) {
Integer ourIP = baseIP + i;
String ip = convertNumericIpToSymbolic(ourIP);
result.add(ip);
}
return result;
}
/**
* Range of hosts
*
*@return
*/
public String getHostAddressRange() {
int numberOfBits;
for (numberOfBits = 0; numberOfBits < 32; numberOfBits++) {
if ((netmaskNumeric << numberOfBits) == 0)
break;
}
Integer numberOfIPs = 0;
for (int n = 0; n < (32 - numberOfBits); n++) {
numberOfIPs = numberOfIPs << 1;
numberOfIPs = numberOfIPs | 0x01;
}
Integer baseIP = baseIPnumeric & netmaskNumeric;
String firstIP = convertNumericIpToSymbolic(baseIP + 1);
String lastIP = convertNumericIpToSymbolic(baseIP + numberOfIPs - 1);
return firstIP + " - " + lastIP;
}
/**
* Returns number of hosts available in given range
*
*@return number of hosts
*/
public Long getNumberOfHosts() {
int numberOfBits;
for (numberOfBits = 0; numberOfBits < 32; numberOfBits++) {
if ((netmaskNumeric << numberOfBits) == 0)
break;
}
Double x = Math.pow(2, (32 - numberOfBits));
if (x == -1)
x = 1D;
return x.longValue();
}
/**
* The XOR of the netmask
*
*@return wildcard mask in text form, i.e. 0.0.15.255
*/
public String getWildcardMask() {
Integer wildcardMask = netmaskNumeric ^ 0xffffffff;
StringBuffer sb = new StringBuffer(15);
for (int shift = 24; shift > 0; shift -= 8) {
// process 3 bytes, from high order byte down.
sb.append(Integer.toString((wildcardMask >>> shift) & 0xff));
sb.append('.');
}
sb.append(Integer.toString(wildcardMask & 0xff));
return sb.toString();
}
public String getBroadcastAddress() {
if (netmaskNumeric == 0xffffffff)
return "0.0.0.0";
int numberOfBits;
for (numberOfBits = 0; numberOfBits < 32; numberOfBits++) {
if ((netmaskNumeric << numberOfBits) == 0)
break;
}
Integer numberOfIPs = 0;
for (int n = 0; n < (32 - numberOfBits); n++) {
numberOfIPs = numberOfIPs << 1;
numberOfIPs = numberOfIPs | 0x01;
}
Integer baseIP = baseIPnumeric & netmaskNumeric;
Integer ourIP = baseIP + numberOfIPs;
String ip = convertNumericIpToSymbolic(ourIP);
return ip;
}
private String getBinary(Integer number) {
String result = "";
Integer ourMaskBitPattern = 1;
for (int i = 1; i <= 32; i++) {
if ((number & ourMaskBitPattern) != 0) {
result = "1" + result; // the bit is 1
} else { // the bit is 0
result = "0" + result;
}
if ((i % 8) == 0 && i != 0 && i != 32)
result = "." + result;
ourMaskBitPattern = ourMaskBitPattern << 1;
}
return result;
}
public String getNetmaskInBinary() {
return getBinary(netmaskNumeric);
}
/**
* Checks if the given IP address contains in subnet
*
*@param IPaddress
*@return
*/
public boolean contains(String IPaddress) {
Integer checkingIP = 0;
String[] st = IPaddress.split("\.");
if (st.length != 4)
throw new NumberFormatException("Invalid IP address: " + IPaddress);
int i = 24;
for (int n = 0; n < st.length; n++) {
int value = Integer.parseInt(st[n]);
if (value != (value & 0xff)) {
throw new NumberFormatException("Invalid IP address: "
+ IPaddress);
}
checkingIP += value << i;
i -= 8;
}
if ((baseIPnumeric & netmaskNumeric) == (checkingIP & netmaskNumeric))
return true;
else
return false;
}
public boolean contains(IPv4 child) {
Integer subnetID = child.baseIPnumeric;
Integer subnetMask = child.netmaskNumeric;
if ((subnetID & this.netmaskNumeric) == (this.baseIPnumeric & this.netmaskNumeric)) {
if ((this.netmaskNumeric < subnetMask) == true
&& this.baseIPnumeric <= subnetID) {
return true;
}
}
return false;
}
/**
*@param args
*/
public static void main(String[] args) {
IPv4 ipv4 = new IPv4("192.168.161.125/30"); //30 is the CIDR for Mask 255.255.255.252
System.out.println(ipv4.getCIDR());
System.out.println(ipv4.getNetmask());
System.out.println(ipv4.getNumberOfHosts());
System.out.println(ipv4.getWildcardMask());
System.out.println(ipv4.getBroadcastAddress());
System.out.println(ipv4.getHostAddressRange());
}
}
回答by Nik Developer
An easy way. Let's suppose we have subnet mask and ip address into 2 strings:
一个简单的方法。假设我们将子网掩码和 IP 地址分成 2 个字符串:
String[] mask = subnetMaskString.split("\.");
String[] ipAddress = ipAddressString.split("\.");
StringBuffer ipSubnet = new StringBuffer();
for(int i=0; i<4; i++)
try{
if(ipSubnet.length()>0)
ipSubnet.append('.');
ipSubnet.append(Integer.parseInt(ipAddress[i]) & Integer.parseInt(mask[i]));
}catch(Exception x){
//Integer parsing exception, wrong ipaddress or mask
break;
}
// if no exception ipSubnet.toString() is the subnet ip //
回答by Sean F
The IPAddress Java librarysupports both IPv4 and IPv6 subnets in a polymorphic manner. Disclaimer: I am the project manager.
IPAddress Java 库以多态方式支持 IPv4 和 IPv6 子网。免责声明:我是项目经理。
Here is sample code for your example with address 192.168.161.125 and subnet mask is 255.255.255.252. It shows three ways of doing it.
这是您示例的示例代码,地址为 192.168.161.125,子网掩码为 255.255.255.252。它显示了三种方法。
The first method parses the string addr/mask:
第一种方法解析字符串 addr/mask:
public static String getNetwork1(String addrStr, String maskStr) throws AddressStringException {
IPAddressString addrString = new IPAddressString(addrStr + IPAddress.PREFIX_LEN_SEPARATOR + maskStr);
IPAddress addr = addrString.toAddress();
IPAddress subnet = addr.toPrefixBlock();
return subnet.toString();
}
The second method masks the address to get the network:
第二种方法屏蔽地址以获取网络:
public static String getNetwork2(String addrStr, String maskStr) throws AddressStringException {
IPAddressString addrString = new IPAddressString(addrStr);
IPAddressString maskString = new IPAddressString(maskStr);
IPAddress addr = addrString.toAddress();
IPAddress mask = maskString.toAddress();
IPAddress masked = addr.mask(mask);
return masked.toString();
}
The third method gets the prefix length from the mask to get the network:
第三种方法从掩码中获取前缀长度得到网络:
public static String getNetwork3(String addrStr, String maskStr) throws AddressStringException {
IPAddressString addrString = new IPAddressString(addrStr);
IPAddressString maskString = new IPAddressString(maskStr);
IPAddress addr = addrString.toAddress();
IPAddress mask = maskString.toAddress();
Integer prefLen = mask.getBlockMaskPrefixLength(true);
IPAddress subnet = addr.setPrefixLength(prefLen).toPrefixBlock();
return subnet.toString();
}
Using the three options:
使用三个选项:
String addrString = "192.168.161.125";
String maskString = "255.255.255.252";
System.out.println(getNetwork1(addrString, maskString));
System.out.println(getNetwork2(addrString, maskString));
System.out.println(getNetwork3(addrString, maskString));
We get the output:
我们得到输出:
192.168.161.124/30
192.168.161.124
192.168.161.124/30
To remove the prefix length on the first and third address result, withoutPrefixLength() can be used.
要删除第一个和第三个地址结果的前缀长度,可以使用 withoutPrefixLength()。