Erlang IPv6 string to Erlang IP tuple and Erlang IP tuple to IPv6 string

As far as we are slownly moving to IPv6 in all aspects of our life I am going to describe converion of IPv6 string (human readabe) representaion into Erlang IP tuple representation. I think that is especially useful for parsing human input from some interface. As you may know Erlang representation of IPv6 address is a tuple of integer values with arity of 8. Something like {0,0,0,0,0,65535,49320,6634} (that is IPv6 representation of IPv6 address) or {8193, 512, 3583, 65521, 534, 16127, 65201, 17623}. The human readable representation of the first IP is 0000:0000:0000:0000:0000:FFFF:C0A8:19EA and the second one is 2001:0200:0DFF:FFF1:0216:3EFF:FEB1:44D7.

 Attention! Method described in this article is more or less good suted for human input parsing, for other sutuations Erlang inet_parse module functions described in my earlier article may be suted better.

So, lets start programming.

Here is the module that is doing all the fun here:

-module(ipv6).
-compile(export_all).

str_to_tuple(Str) when is_list(Str)->
	case io_lib:fread("~16u:~16u:~16u:~16u:~16u:~16u:~16u:~16u", Str) of
	{ok, Lst, _} ->
		list_to_tuple(Lst);
	_ ->
		error
	end.
	
bin_to_tuple(Str) when is_binary(Str)->
	case io_lib:fread("~16u:~16u:~16u:~16u:~16u:~16u:~16u:~16u", binary_to_list(Str)) of
	{ok, Lst, _} ->
		list_to_tuple(Lst);
	_ ->
		error
	end.
	
tuple_to_str(Tuple)->
	lists:flatten(io_lib:format("~4.16.0B:~4.16.0B:~4.16.0B:~4.16.0B:~4.16.0B:~4.16.0B:~4.16.0B:~4.16.0B", tuple_to_list(Tuple))).
	
tuple_to_bin(Tuple)->
	list_to_binary(io_lib:format("~4.16.0B:~4.16.0B:~4.16.0B:~4.16.0B:~4.16.0B:~4.16.0B:~4.16.0B:~4.16.0B", tuple_to_list(Tuple))).

Module is very simple and do not requires a lot of explanations, so only thing that I will mention that this module is capable to accept and output IP addresses in list and binary formats.

And here is some usage examples:

Eshell V5.8.5  (abort with ^G)
1> ipv6:bin_to_tuple(<<"0:0:0:0:0:ffff:c0a8:19ea">>).
{0,0,0,0,0,65535,49320,6634}
2> ipv6:tuple_to_bin(ipv6:bin_to_tuple(<<"0:0:0:0:0:ffff:c0a8:19ea">>)).
<<"0000:0000:0000:0000:0000:FFFF:C0A8:19EA">>
3> ipv6:str_to_tuple("2001:0200:0DFF:FFF1:0216:3EFF:FEB1:44D7").
{8193,512,3583,65521,534,16127,65201,17623}
4> ipv6:tuple_to_str(ipv6:str_to_tuple("2001:0200:0DFF:FFF1:0216:3EFF:FEB1:44D7")).
"2001:0200:0DFF:FFF1:0216:3EFF:FEB1:44D7"
5> 

First line converst IP address from binary string to Erlang tuple. Second line converst IP from binary string to tuple and again to binary string. Third line converst IP from string representation to Erlang tuple. Forth one converst IP string to Erlang tuple and again to string representation. So,  that allows us to compare input and output of the functions and ensure that everything is correct.

Attention! If you do not need to parse human input to convert string to Erlang IP tuple you should use built-in Erlang IP parsing functions

 
Posted by:
Enjoyed this post? Share and Leave a comment below, thanks! :)