gsamaras
gsamaras

Reputation: 73366

How to convert an IPv6 address to a binary string?

How to convert an IPv6 address to a binary string?

Example:

IPv6:    2001:0db8:85a3:0000:0000:8a2e:0370:7334
Binary:  0010000000000001 0000110110111000 1000010110100011 0000000000000000 0000000000000000 1000101000101110 0000001101110000 0111001100110100 

I want to do this in Java. Here is my failed attempt (I do not ask for a solution related to this attempt whatsoever):

Implemented in C++, where I am more familiar:

#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;
}

which is buggy and produces a wrong result ("1010100011000000").


PS: There is an IPv6 to Binary calculator online, which might help you when testing.

Upvotes: 2

Views: 4020

Answers (3)

Sean F
Sean F

Reputation: 4595

The open-source IPAddress Java library can produce many different string formats, one of them being a binary string. Disclaimer: I am the project manager of the IPAddress library.

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);

Output:

00100000000000010000110110111000100001011010001100000000000000000000000000000000100010100010111000000011011100000111001100110100

Note that this handles the various different ways of representing IPv6 addresses (such as with compressed segments, or with embedded IPv4 as final segments). Also note the code works equally well for IPv4 addresses.

Upvotes: 2

Juan Carlos Mendoza
Juan Carlos Mendoza

Reputation: 5794

You can also do it this way:

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);

Output:

0010000000000001 0000110110111000 1000010110100011 0000000000000000 0000000000000000 1000101000101110 0000001101110000 0111001100110100 

EDIT

The previous solution won't work when the given IPv6 address is compressed. For example 3210:0000:0000:0000:0000:0000:0000:0000 can be shortened to 3210:: and is worth to mention that in those cases the solutions proposed so far won't work if we don't handle this first. To solve that issue you can do this:

String ipv6CompressedAddress = "3210::";
Inet6Address ipv6Address = (Inet6Address) Inet6Address.getByName(ipv6CompressedAddress);
String ipv6 = ipv6Address.getCanonicalHostName(); // 3210:0:0:0:0:0:0:0

Here I'm using Java's IPv6 representation class Inet6Address to get a less compressed ip address. Then we can use the methods shown earlier to convert it to binary.

Upvotes: 2

Youcef LAIDANI
Youcef LAIDANI

Reputation: 59950

Try this solution :

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);

If you are using Java 8 you can use :

String result = Stream.of(ipv6.split(":"))
      .map(s -> String.format("%16s", new BigInteger(s, 16).toString(2)).replace(' ', '0'))
      .collect(Collectors.joining(" "));

Output

0010000000000001 0000110110111000 1000010110100011 0000000000000000 0000000000000000 1000101000101110 0000001101110000 0111001100110100

Upvotes: 5

Related Questions