4

Q: Write a program that prompts the user for an IP address then converts this to a base 10, binary and hex value. The program then converts the hex value to an RFC3056 IPv6 6to4 address.

I have the base 10 and binary parts working but I can't seem to get my head around the hex part. Can the format string method be used somehow to accomplish the same thing? Or would I need to import the ipaddress module in this case?

#!/usr/bin/python3

ip_address = input("Please enter a dot decimal IP Address: ")

"""This part converts to base 10"""
ListA = ip_address.split(".")
ListA = list(map(int, ListA))
ListA = ListA[0]*(256**3) + ListA[1]*(256**2) + ListA[2]*(256**1) + ListA[3]
print("The IP Address in base 10 is: " , ListA)

"""This part converts to base 2"""
base2 = [format(int(x), '08b') for x in ip_address.split('.')]
print("The IP Address in base 2 is: ", base2)

"""This part converts to hex"""
hexIP = []
[hexIP.append(hex(int(x))[2:].zfill(2)) for x in ip_address.split('.')]
hexIP = "".join(hexIP)
print("The IP Address in hex is: " , hexIP)

EDIT: Managed to convert the IP Address to hex value. Now how do I convert this hex value into IPv6 address?

4 Answers 4

7
>>> ip_address = '123.45.67.89'
>>> numbers = list(map(int, ip_address.split('.')))
>>> '2002:{:02x}{:02x}:{:02x}{:02x}::'.format(*numbers)
'2002:7b2d:4359::'
Sign up to request clarification or add additional context in comments.

5 Comments

6to4 address must start with '2002::/16' i.e., '2002:7b2d:4359::' in your example.
Changed it to: '2002:0:0:0:0:ffff:{:02x}{:02x}:{:02x}{:02x}'.format(*numbers)
Doesn't account for the subnet, but it will do for now.
@user1819786: 0:0:0:0:ffff: is also incorrect in this case. Click both links in my previous comment.
@J.F.Sebastian, Thank you for comment and links. I update the answer according to your comment.
4

In Python 3.3 you could use ipaddress module to manipulate IPv4, IPv6 addresses:

#!/usr/bin/env python3
import ipaddress

# get ip address 
while True:
    ip4str = input("Enter IPv4 (e.g., 9.254.253.252):")
    try:
        ip4 = ipaddress.IPv4Address(ip4str)
    except ValueError:
        print("invalid ip address. Try, again")
    else:
        break # got ip address

# convert ip4 to rfc 3056 IPv6 6to4 address
# http://tools.ietf.org/html/rfc3056#section-2
prefix6to4 = int(ipaddress.IPv6Address("2002::"))
ip6 = ipaddress.IPv6Address(prefix6to4 | (int(ip4) << 80))
print(ip6)
assert ip6.sixtofour == ip4

# convert ip4 to a base 10
print(int(ip4))
# convert ip4 to binary (0b)
print(bin(int(ip4)))
# convert ip4 to hex (0x)
print(hex(int(ip4)))

Comments

2

If you just want to use the IPv4 addresses in an IPv6 context (e.g. by passing to socket.connect() created using the socket.AF_INET6 address family), you can just use the syntax described in RFC4291, Section 2.2:

>>> import socket
>>> a = '10.20.30.40'
>>> s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)
>>> s.connect(('2002::' + a, 9))

I.e. just prepend ::ffff: to the IPv4 address and you get a valid 6to4 address. If you instead want to convert this address to the more common hexadecimal form, I suggest using the standard library ipaddress module you mentioned:

>>> import ipaddress
>>> a = '10.20.30.40'
>>> print(ipaddress.IPv6Address('2002::' + a).compressed)
'2002::a14:1e28'

Comments

0

Before referring to the solution, have a look at this doc for conversion and convention of ipv6 representation.

def ipconversion4to6(ipv4_address):
    hex_number = ["{:02x}".format(int(_)) for _ in address.split(".")]
    ipv4 = "".join(hex_number)
    ipv6 = "2002:"+ipv4[:4]+":"+ipv4[4:]+"::"
    return ipv6

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.