A pale, hoppy library for working with Internet Protocol Addresses.
Currently only supports individual addresses and not networks, and only classic IPv4, not modern IPv6, sorry.
If available in Hex, the package can be installed as:
Add ipa to your list of dependencies in
mix.exs:def deps do [{:ipa, "~> 0.0.2"}] end
Ensure ipa is started before your application:
def application do [applications: [:ipa]] end
The following functions are available in the IPA module:
Check if a dotted decimal, dotted binary, hexadecimal, binary or 4-element tuple IP address is valid:
iex>IPA.valid_address?("192.168.0.1")trueiex>IPA.valid_address?("192.168.0.256")falseiex>IPA.valid_address?("192.168.0")falseiex>IPA.valid_address?("192.168.0.1.1")falseiex>IPA.valid_address?("11000000.10101000.00000000.00000001")trueiex>IPA.valid_address?("0xC0A80001")trueiex>IPA.valid_address?("0b11000000101010000000000000000001")trueiex>IPA.valid_address?({192,168,0,1})trueThis validity is slightly imperfect as it does not recognise the fact that 127.1 can be considered a valid IP address that translates to 127.0.0.1.
Check if a dotted decimal, dotted binary or CIDR notation subnet mask is valid:
iex>IPA.valid_mask?("255.255.255.0")trueiex>IPA.valid_mask?("192.168.0.1")falseiex>IPA.valid_mask?(24)trueiex>IPA.valid_mask?(33)falseiex>IPA.valid_mask?("11111111.11111111.11111111.00000000")trueiex>IPA.valid_mask?("10101000.10101000.00000000.00000000")falseiex>IPA.valid_mask?("0xFFFFFF00")trueiex>IPA.valid_mask?("0b11111111111111111111111100000000")trueiex>IPA.valid_mask?({255,255,255,0})trueTransform an address or mask between dotted decimal, dotted binary, hexadecimal, binary, 4-element tuple and CIDR representation:
# IPA.to_bits# dotted decimal -> dotted binaryiex>IPA.to_bits("192.168.0.1")"11000000.10101000.00000000.00000001"# hexadecimal -> dotted binaryiex>IPA.to_bits("0xC0A80001")"11000000.10101000.00000000.00000001"# tuple -> dotted binaryiex>IPA.to_bits({192,168,0,1})"11000000.10101000.00000000.00000001"# binary -> dotted binaryiex>IPA.to_bits("0b11000000101010000000000000000001")"11000000.10101000.00000000.00000001"# cidr -> dotted binaryiex>IPA.to_bits(24)"11111111.11111111.11111111.00000000"# invalid addressiex>IPA.to_bits("192.168.0.256")**(IPError) Invalid IP Address
# IPA.to_hex# dotted decimal -> hexadecimaliex>IPA.to_hex("192.168.0.1")"0xC0A80001"# binary -> hexadecimaliex>IPA.to_hex("0b11000000101010000000000000000001")"0xC0A80001"# dotted binary -> hexadecimaliex>IPA.to_hex("11000000.10101000.00000000.00000001")"0xC0A80001"# tuple -> hexadecimaliex>IPA.to_hex({192,168,0,1})"0xC0A80001"# cidr -> hexadecimaliex>IPA.to_hex(24)"0xFFFFFF00"# invalid addressesiex>IPA.to_hex("192.168.0.256")**(IPError) Invalid IP Address
iex>IPA.to_hex("0b11000000101010000000000000000002")**(IPError) Invalid IP Address
# IPA.to_binary# dotted decimal -> binaryiex>IPA.to_binary("192.168.0.1")"0b11000000101010000000000000000001"# hexadecimal -> binaryiex>IPA.to_binary("0xC0A80001")"0b11000000101010000000000000000001"# dotted binary -> binaryiex>IPA.to_binary("11000000.10101000.00000000.00000001")"0b11000000101010000000000000000001"# tuple -> binaryiex>IPA.to_binary({192,168,0,1})"0b11000000101010000000000000000001"# cidr -> binaryiex>IPA.to_binary(24)"0b11111111111111111111111100000000"# invalid addressiex>IPA.to_binary({192,168,0,256})**(IPError) Invalid IP Address
# IPA.to_octets# dotted decimal address -> tupleiex>IPA.to_octets("192.168.0.1"){192,168,0,1}# dotted decimal mask -> tupleiex>IPA.to_octets("255.255.255.0"){255,255,255,0}# binary -> tupleiex>IPA.to_octets("0b11000000101010000000000000000001"){192,168,0,1}# hexadecimal -> tupleiex>IPA.to_octets("0xC0A80001"){192,168,0,1}# dotted binary -> tupleiex>IPA.to_octets("11000000.10101000.00000000.00000001"){192,168,0,1}# invalid addressiex>IPA.to_octets("192.168.0.256")**(IPError) Invalid IP Address
# IPA.to_dotted_dec# cidr -> dotted decimaliex>IPA.to_dotted_dec(24)"255.255.255.0"# tuple -> dotted decimaliex>IPA.to_dotted_dec({192,168,0,1})"192.168.0.1"# binary -> dotted decimaliex>IPA.to_dotted_dec("0b11000000101010000000000000000001")"192.168.0.1"# hexadecimal -> dotted decimaliex>IPA.to_dotted_dec("0xC0A80001")"192.168.0.1"# dotted binary -> dotted decimaliex>IPA.to_dotted_dec("11000000.10101000.00000000.00000001")"192.168.0.1"# invalid mask/addressiex>IPA.to_dotted_dec(33)**(SubnetError) Invalid Subnet Mask
iex>IPA.to_dotted_dec({192,168,0,256})**(IPError) Invalid IP Address
# IPA.to_cidr# dotted decimal to cidriex>IPA.to_cidr("255.255.255.0")24# hexadecimal -> cidriex>IPA.to_cidr("0xFFFFFF00")24# binary -> cidriex>IPA.to_cidr("0b11111111111111111111111100000000")24# tuple -> cidriex>IPA.to_cidr({255,255,255,0})24# invalid maskiex>IPA.to_cidr("192.168.0.1")**(SubnetError) Invalid Subnet MaskFind out if the address is part of a reserved private address block (ie. NOT a public address):
iex>IPA.reserved?("192.168.0.1")trueiex>IPA.reserved?("8.8.8.8")falseFind out which reserved block of addresses an address is a part of. If not reserved it will be public, obvs. A full list of reserved blocks can be found in the docs:
iex>IPA.block("192.168.0.1"):rfc1918iex>IPA.block("10.0.1.0"):rfc1918iex>IPA.block("127.0.0.1"):loopbackiex>IPA.block("8.8.8.8"):publicRun mix test. DocTests included.
Docs are available on hexdocs or by running mix docs.
Honestly, I don't know how much time I'm actually going to be able to dedicate to this project, so maybe think carefully before using it in production code (ha, high hopes!), but perhaps it can at least provide a starting point for something better?