如何将IPv6地址转换为二进制字符串?
示例:
IPv6: 2001:0db8:85a3:0000:0000:8a2e:0370:7334
Binary: 0010000000000001 0000110110111000 1000010110100011 0000000000000000 0000000000000000 1000101000101110 0000001101110000 0111001100110100
我想用Java做到这一点。这是我失败的尝试(我没有要求与此尝试相关的解决方案):
在C ++中实现,我更熟悉:
#include <iostream>
#include <string>
#define _BSD_SOURCE
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
std::string toBinary(unsigned long int decimalIpV6)
{
std::string r;
while(decimalIpV6!=0) {r=(decimalIpV6%2==0 ?"0":"1")+r; decimalIpV6/=2;}
return r;
}
unsigned long int ipV6toDecimal(std::string binaryString) {
struct sockaddr_in antelope;
inet_aton(binaryString.c_str(), &antelope.sin_addr); // store IP in antelope
// and this call is the same as the inet_aton() call, above:
antelope.sin_addr.s_addr = inet_addr(binaryString.c_str());
return antelope.sin_addr.s_addr;
}
int main() {
std::string ipv6 = "192.168.0.0";
unsigned long int ipv6decimal= ipV6toDecimal(ipv6);
std::cout << toBinary(ipv6decimal) << std::endl;
return 0;
}
这是错误的,并产生错误的结果(“1010100011000000”)。
PS:有一个IPv6到二进制计算器online,它可能在测试时帮助你。
答案 0 :(得分:5)
试试这个解决方案:
String ipv6 = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
String[] spl = ipv6.split(":");
String result = "", del = "";
for (String s : spl) {
result += del
+ String.format("%16s", new BigInteger(s, 16).toString(2)).replace(' ', '0');
del = " ";
}
System.out.println(result);
如果您使用的是Java 8,则可以使用:
String result = Stream.of(ipv6.split(":"))
.map(s -> String.format("%16s", new BigInteger(s, 16).toString(2)).replace(' ', '0'))
.collect(Collectors.joining(" "));
输出
0010000000000001 0000110110111000 1000010110100011 0000000000000000 0000000000000000 1000101000101110 0000001101110000 0111001100110100
答案 1 :(得分:2)
你也可以这样做:
String ipv6 = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
String result = "";
for (String s : ipv6.split(":")) {
int value = Integer.parseInt(s, 16);
result += String.format("%16s", Integer.toBinaryString(value)).replace(' ', '0') + " ";
}
System.out.println(result);
输出:
0010000000000001 0000110110111000 1000010110100011 0000000000000000 0000000000000000 1000101000101110 0000001101110000 0111001100110100
修改强>
以前的解决方案在压缩给定的IPv6地址时不起作用。例如,3210:0000:0000:0000:0000:0000:0000:0000
可缩短为3210::
,值得一提的是,在这些情况下,如果我们不首先处理此问题,目前提出的解决方案将无法运行。要解决该问题,您可以这样做:
String ipv6CompressedAddress = "3210::";
Inet6Address ipv6Address = (Inet6Address) Inet6Address.getByName(ipv6CompressedAddress);
String ipv6 = ipv6Address.getCanonicalHostName(); // 3210:0:0:0:0:0:0:0
我在这里使用Java's IPv6 representation class Inet6Address来获得压缩程度较低的IP地址。然后我们可以使用前面显示的方法将其转换为二进制。
答案 2 :(得分:1)
open-source IPAddress Java library可以产生许多不同的字符串格式,其中之一是二进制字符串。免责声明:我是IPAddress库的项目经理。
String str = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
IPAddressString addrStr = new IPAddressString(str);
IPAddress addr = addrStr.getAddress();
String binaryStr = addr.toBinaryString();
System.out.println(binaryStr);
输出:
00100000000000010000110110111000100001011010001100000000000000000000000000000000100010100010111000000011011100000111001100110100
请注意,这处理了表示IPv6地址的各种不同方式(例如使用压缩段或将嵌入式IPv4作为最终段)。还要注意,该代码对于IPv4地址同样有效。