Skip to content

Instantly share code, notes, and snippets.

@lafka
Created August 31, 2014 19:03
Show Gist options
  • Save lafka/8eaa439b090122c610ff to your computer and use it in GitHub Desktop.
Save lafka/8eaa439b090122c610ff to your computer and use it in GitHub Desktop.
IPv6 address expansion in elixir
defmodule IP6 do
def parse(rest), do: parse(String.downcase(rest), "", [])
def parse("", "", acc), do: Enum.reverse(acc) |> Enum.map(fn(val) ->
case String.contains? val, "." do
true ->
val
false ->
val = "0000" <> val
String.slice val, byte_size(val)-4, byte_size(val)
end
end)
def parse("", part, acc), do: parse("", "", [part | acc])
def parse(<<"::", rest :: binary>>, part, acc) do
tail = Enum.reverse(parse(rest))
slice = List.duplicate "", 8 - (length(tail) + length(acc) + 1)
parse("", "", tail ++ slice ++ [part | acc])
end
def parse(<<":", rest :: binary>>, part, acc), do:
parse(rest, "", [part | acc])
def parse(<<byte :: binary-size(1), rest :: binary>>, part, acc), do:
parse(rest, part <> byte, acc)
end
items = [
localhost: [["0000", "0000", "0000", "0000", "0000", "0000", "0000", "0001"], "::1"],
interfacelocal: [["ff01", "0000", "0000", "0000", "0000", "0000", "0000", "0001"], "ff01::1"],
any: [["0000", "0000", "0000", "0000", "0000", "0000", "0000", "0000"], "::"],
a101: [["2001", "0000", "5ef5", "79fb", "1463", "2c82", "fda0", "d5d3"], "2001:0:5ef5:79fb:1463:2c82:fda0:d5d3"],
a102: [["2001", "0000", "5ef5", "79fd", "08d6", "1c03", "52f0", "fa46"], "2001:0:5ef5:79fd:8d6:1c03:52f0:fa46"],
a103: [["2001", "0000", "d911", "c0d9", "20c2", "3844", "f191", "3af8"], "2001:0:d911:c0d9:20c2:3844:f191:3af8"],
a104: [["ff01", "0000", "0000", "0000", "0000", "0000", "0000", "0001"], "FF01:0:0:0:0:0:0:1"],
a105: [["ff01", "0000", "0000", "0000", "0000", "0000", "0000", "0002"], "FF01:0:0:0:0:0:0:2"],
a106: [["ff01", "0000", "0000", "0000", "0000", "0000", "0000", "000c"], "FF01:0:0:0:0:0:0:C"],
a107: [["ff01", "0000", "0000", "0000", "0000", "0000", "0000", "00fb"], "FF01:0:0:0:0:0:0:FB"],
a108: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "0001"], "FF02:0:0:0:0:0:0:1"],
a109: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "0002"], "FF02:0:0:0:0:0:0:2"],
a110: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "0003"], "FF02:0:0:0:0:0:0:3"],
a111: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "0004"], "FF02:0:0:0:0:0:0:4"],
a112: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "0005"], "FF02:0:0:0:0:0:0:5"],
a113: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "0006"], "FF02:0:0:0:0:0:0:6"],
a114: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "0007"], "FF02:0:0:0:0:0:0:7"],
a115: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "0008"], "FF02:0:0:0:0:0:0:8"],
a116: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "0009"], "FF02:0:0:0:0:0:0:9"],
a117: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "000a"], "FF02:0:0:0:0:0:0:A"],
a118: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "000b"], "FF02:0:0:0:0:0:0:B"],
a119: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "000c"], "FF02:0:0:0:0:0:0:C"],
a120: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "000d"], "FF02:0:0:0:0:0:0:D"],
a121: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "000e"], "FF02:0:0:0:0:0:0:E"],
a122: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "000f"], "FF02:0:0:0:0:0:0:F"],
a123: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "0010"], "FF02:0:0:0:0:0:0:10"],
a124: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "0012"], "FF02:0:0:0:0:0:0:12"],
a125: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "0016"], "FF02:0:0:0:0:0:0:16"],
a126: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "001a"], "FF02:0:0:0:0:0:0:1A"],
a127: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "006a"], "FF02:0:0:0:0:0:0:6A"],
a128: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "006b"], "FF02:0:0:0:0:0:0:6B"],
a129: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "006c"], "FF02:0:0:0:0:0:0:6C"],
a130: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "006d"], "FF02:0:0:0:0:0:0:6D"],
a131: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "006e"], "FF02:0:0:0:0:0:0:6E"],
a132: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "006f"], "FF02:0:0:0:0:0:0:6F"],
a133: [["ff02", "0000", "0000", "0000", "0000", "0000", "0000", "00fb"], "FF02:0:0:0:0:0:0:FB"],
a134: [["ff02", "0000", "0000", "0000", "0000", "0000", "0001", "0001"], "FF02::1:1"],
a135: [["ff02", "0000", "0000", "0000", "0000", "0000", "0001", "0002"], "FF02:0:0:0:0:0:1:2"],
a136: [["ff02", "0000", "0000", "0000", "0000", "0000", "0001", "0003"], "FF02:0:0:0:0:0:1:3"],
a137: [["ff02", "0000", "0000", "0000", "0000", "0000", "0001", "0004"], "FF02:0:0:0:0:0:1:4"],
a138: [["ff02", "0000", "0000", "0000", "0000", "0000", "0001", "0005"], "FF02:0:0:0:0:0:1:5"],
a139: [["ff02", "0000", "0000", "0000", "0000", "0000", "0001", "0006"], "FF02:0:0:0:0:0:1:6"],
a140: [["ff05", "0000", "0000", "0000", "0000", "0000", "0000", "0002"], "FF05:0:0:0:0:0:0:2"],
a141: [["ff05", "0000", "0000", "0000", "0000", "0000", "0000", "000c"], "FF05:0:0:0:0:0:0:C"],
a142: [["ff05", "0000", "0000", "0000", "0000", "0000", "0000", "00fb"], "FF05:0:0:0:0:0:0:FB"],
a143: [["ff05", "0000", "0000", "0000", "0000", "0000", "0000", "00fc"], "FF05:0:0:0:0:0:0:FC"],
a144: [["ff05", "0000", "0000", "0000", "0000", "0000", "0000", "0117"], "FF05:0:0:0:0:0:0:117"],
a145: [["ff05", "0000", "0000", "0000", "0000", "0000", "0000", "0183"], "FF05:0:0:0:0:0:0:183"],
a146: [["ff05", "0000", "0000", "0000", "0000", "0000", "0000", "018c"], "FF05:0:0:0:0:0:0:18C"],
a147: [["ff05", "0000", "0000", "0000", "0000", "0000", "0000", "0202"], "FF05::202"],
a148: [["ff05", "0000", "0000", "0000", "0000", "0000", "0000", "0205"], "FF05:0:0:0:0:0:0:205"],
a149: [["ff05", "0000", "0000", "0000", "0000", "0000", "0000", "0300"], "FF05:0:0:0:0:0:0:300"],
a150: [["ff05", "0000", "0000", "0000", "0000", "0000", "0000", "bac0"], "FF05:0:0:0:0:0:0:BAC0"],
a151: [["ff05", "0000", "0000", "0000", "0000", "0000", "0001", "0003"], "FF05:0:0:0:0:0:1:3"],
a152: [["ff05", "0000", "0000", "0000", "0000", "0000", "0001", "0004"], "FF05:0:0:0:0:0:1:4"],
a153: [["ff05", "0000", "0000", "0000", "0000", "0000", "0001", "0005"], "FF05:0:0:0:0:0:1:5"],
a154: [["0403", "9000", "1000", "0000", "0000", "0000", "0000", "0015"], "403:9000:1000::15"],
a155: [["2002", "cb0a", "3cdd", "0001", "0000", "0000", "0000", "0001"], "2002:cb0a:3cdd:1::1"],
a156: [["2001", "0000", "4136", "e378", "8000", "63bf", "3fff", "fdd2"], "2001:0000:4136:e378:8000:63bf:3fff:fdd2"],
a157: [["0000", "0000", "0000", "0000", "0000", "0000", "ffff", "192.0.2.47"], "::ffff:192.0.2.47"],
a158: [["fe8f", "0db8", "0001", "0002", "020c", "29ff", "fe0c", "47d5"], "fe8f:db8:1:2:020c:29ff:fe0c:47d5"],
a159: [["2a02", "2f0c", "8000", "0019", "0062", "0231", "0075", "0133"], "2a02:2f0c:8000:19:62:231:75:133"],
a160: [["2a03", "0280", "0000", "0001", "0000", "0000", "0000", "0001"], "2a03:280:0:1::1"],
a161: [["2403", "9000", "1000", "0000", "0000", "0000", "0000", "0015"], "2403:9000:1000::15"],
a162: [["2a01", "7e00", "0000", "0000", "0000", "0000", "0020", "deed"], "2a01:7e00::20:deed"],
a163: [["ff5f", "0311", "c05a", "c9fa", "3043", "3cff", "fef2", "e00d"], "ff5f:311:c05a:c9fa:3043:3cff:fef2:e00d"],
a164: [["ffad", "4c39", "33e4", "2639", "351f", "f6ff", "fe69", "c0ff"], "ffad:4c39:33e4:2639:351f:f6ff:fe69:c0ff"],
a165: [["ff81", "134f", "52d5", "8e94", "a556", "bcff", "fe69", "3f63"], "ff81:134f:52d5:8e94:a556:bcff:fe69:3f63"],
a166: [["fe80", "0000", "0000", "0000", "0200", "5aee", "feaa", "20a2"], "fe80::200:5aee:feaa:20a2"],
a167: [["2001", "0002", "006c", "0000", "0000", "0000", "0000", "0430"], "2001:0002:6c::430"],
a168: [["2001", "0010", "0240", "00ab", "0000", "0000", "0000", "000a"], "2001:10:240:ab::a"],
a169: [["ff01", "0000", "0000", "0000", "0000", "0000", "0000", "0002"], "ff01:0:0:0:0:0:0:2"],
a170: [["ff01", "0000", "0000", "0000", "0000", "0000", "0000", "0002"], "ff01::2"],
a171: [["2a01", "0270", "0000", "666f", "0000", "0000", "0000", "0001"], "2a01:270:0:666f::1"],
a172: [["2001", "0820", "0002", "0000", "0000", "0000", "0000", "0006"], "2001:820:2::6"],
a173: [["2001", "06b0", "000e", "2018", "0000", "0000", "0000", "0172"], "2001:6b0:e:2018::172"],
a174: [["2001", "0708", "0040", "2001", "a822", "baff", "fec4", "2428"], "2001:708:40:2001:a822:baff:fec4:2428"],
a175: [["2001", "41c8", "0000", "03ee", "0000", "0000", "0000", "0002"], "2001:41c8:0:3ee::2"],
a176: [["2001", "4800", "7802", "0053", "0000", "0000", "0000", "b075"], "2001:4800:7802:53::b075"],
a177: [["2620", "0000", "0861", "0052", "0208", "0080", "0155", "0068"], "2620::861:52:208:80:155:68"],
a178: [["2610", "0150", "2c68", "0000", "0000", "00d0", "0dab", "1de5"], "2610:150:2c68::d0:dab:1de5"],
a179: [["2001", "16d8", "c002", "0000", "0000", "0000", "0000", "0046"], "2001:16d8:c002::46"],
a180: [["2001", "16d8", "0000", "0000", "0000", "0000", "0000", "0046"], "2001:16d8:0000:0000:0000:0000:0000:0046"],
a181: [["fdf8", "f53b", "82e4", "0000", "0000", "0000", "0000", "0053"], "fdf8:f53b:82e4::53"]
]
for {_k, [expect, addr]} <- items do
res = IP6.parse addr
cond do
expect == res ->
nil
true ->
IO.puts "err: #{addr} should expand to #{Enum.join(expect, ":")}, got #{Enum.join(res, ":")}"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment