Data update
This commit is contained in:
parent
72eb4943cb
commit
4d5544505c
2347 changed files with 62432 additions and 16731 deletions
53
Task/Parse-an-IP-Address/Erlang/parse-an-ip-address.erl
Normal file
53
Task/Parse-an-IP-Address/Erlang/parse-an-ip-address.erl
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
#!/usr/bin/env escript
|
||||
-module(ipparse).
|
||||
|
||||
-export([main/1]).
|
||||
|
||||
main([]) ->
|
||||
[print(A, parse(A)) || A <- data()],
|
||||
erlang:halt(0);
|
||||
main(Args) ->
|
||||
[print(A, parse(A)) || A <- Args],
|
||||
erlang:halt(0).
|
||||
|
||||
-spec parse(Input :: string()) ->
|
||||
{Family :: 'IPv6' | 'IPv4', Hex :: binary(), Port :: string()} |
|
||||
{Family :: 'IPv6' | 'IPv4', Hex :: binary()}.
|
||||
parse([$[ | Addr0]) ->
|
||||
case string:split(Addr0, "]", trailing) of
|
||||
[Addr] ->
|
||||
{"IPv6", to_hex(inet:parse_address(Addr))};
|
||||
[Addr, [$: | Port]] ->
|
||||
{"IPv6", to_hex(inet:parse_address(Addr)), Port}
|
||||
end;
|
||||
parse(Addr0) ->
|
||||
case inet:parse_address(Addr0) of
|
||||
{error, einval} ->
|
||||
[Addr, Port] = string:split(Addr0, ":", trailing),
|
||||
{"IPv4", to_hex(inet:parse_address(Addr)), Port};
|
||||
{ok, V6Addr} ->
|
||||
{"IPv6", to_hex({ok, V6Addr})}
|
||||
end.
|
||||
|
||||
-spec to_hex({ok, inet:ip_address()}) -> Hex :: binary().
|
||||
to_hex({ok, {A,B,C,D}}) ->
|
||||
binary:encode_hex(<<A:8, B:8, C:8, D:8>>);
|
||||
to_hex({ok, {A,B,C,D,E,F,G,H}}) ->
|
||||
binary:encode_hex(<<A:16, B:16, C:16, D:16, E:16, F:16, G:16, H:16>>).
|
||||
|
||||
print(Input, {Family, Hex, Port}) ->
|
||||
io:format("Input: ~s~nFamily: ~s~nHex: ~s~nPort: ~s~n~n",
|
||||
[Input, Family, Hex, Port]);
|
||||
print(Input, {Family, Hex}) ->
|
||||
io:format("Input: ~s~nFamily: ~s~nHex: ~s~n~n",
|
||||
[Input, Family, Hex]).
|
||||
|
||||
data() ->
|
||||
["127.0.0.1",
|
||||
"127.0.0.1:80",
|
||||
"::ffff:127.0.0.1",
|
||||
"::1",
|
||||
"[::1]:80",
|
||||
"1::80",
|
||||
"2605:2700:0:3::4713:93e3",
|
||||
"[2605:2700:0:3::4713:93e3]:80"].
|
||||
158
Task/Parse-an-IP-Address/Lua/parse-an-ip-address-1.lua
Normal file
158
Task/Parse-an-IP-Address/Lua/parse-an-ip-address-1.lua
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
local Format = string.format
|
||||
local tonumber = tonumber
|
||||
local ipairs = ipairs
|
||||
local Rep = string.rep
|
||||
|
||||
-- there is no | so this is the best we can do in pure lua patt
|
||||
local ipv4_addr_patt = "[12]?%d?%d%.[12]?%d?%d%.[12]?%d?%d%.[12]?%d?%d"
|
||||
local ipv4_patt = "^(" .. ipv4_addr_patt .. "):?(%d*)$"
|
||||
|
||||
-- ipv4 -> addr?, port?
|
||||
local V4Parse = function (ipv4)
|
||||
local addr, port = ipv4:match(ipv4_patt)
|
||||
if addr then
|
||||
for digitS in addr:gmatch"%d+" do
|
||||
if tonumber(digitS)>255 then return nil end
|
||||
end
|
||||
end
|
||||
return addr, port
|
||||
end
|
||||
|
||||
-- no check
|
||||
local V4ToHex = function (ipv4_addr)
|
||||
local hex = Format(
|
||||
"%.2x%.2x%.2x%.2x"
|
||||
, ipv4_addr:match"^(%d+)%.(%d+)%.(%d+)%.(%d+)$"
|
||||
)
|
||||
return hex, tonumber("0x" .. hex)
|
||||
end
|
||||
|
||||
-- ipv4_address -> addr?, port?, hex?
|
||||
local V4 = function (ipv4) -- "address:port" -> address:str|nil, port:str|nil, hex:str|nil
|
||||
local addr, port = V4Parse(ipv4)
|
||||
if addr then
|
||||
return addr, port, V4ToHex(addr)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--------------------------------- IPV6 Section
|
||||
local ipv6_patternsT do
|
||||
local v6 = "([%x:]*:[%x:]*:[%x:]*)"
|
||||
local v64 = "([%x:]*:[%x:]*:" .. ipv4_addr_patt .. ")"
|
||||
|
||||
ipv6_patternsT = { -- these are guessers/approximators
|
||||
-- [addr]
|
||||
"^%[" .. v6 .. "%]:(%d+)$" -- [v6]:port
|
||||
,"^%[" .. v6 .. "%]$" -- [v6]
|
||||
,"^%[" .. v64 .. "%]:(%d+)$" -- [v6+v4]:port
|
||||
,"^%[" .. v64 .. "%]$" -- [v6+v4]
|
||||
|
||||
-- guesswork
|
||||
,"^" .. v64 .. ":(%d+)$" -- v6+v4+port
|
||||
-- TODO: unsure if v6+v4[#p:.]port is valid
|
||||
|
||||
,"^(" .. v64 .. ")$" -- v6+v4
|
||||
|
||||
,"^" .. v6 .. "[.p#](%d+)$" -- v6+port
|
||||
-- portsep=":" handled bellow
|
||||
-- There is no way to use port while using : as the port separator
|
||||
-- the only method is if its complete or if its :::80
|
||||
, "^([%x:]*::):(%d+)$" -- v6+port
|
||||
-- Complete
|
||||
,"^(" .. ("%x*:"):rep(7) .. "%x*):(%d+)$" -- v6+port
|
||||
|
||||
,"^" .. v6 .. "$" -- v6
|
||||
}
|
||||
end
|
||||
|
||||
-- addr, port -- nil if failure
|
||||
-- addr will be returned as
|
||||
-- ipv6_address port -> address, port, mini hexified address (no ipv4)
|
||||
local V6Parse = function (ipv6_address)
|
||||
-- get the port, then get the ip via position
|
||||
for _,match in ipairs(ipv6_patternsT) do
|
||||
local address, port = ipv6_address:match(match)
|
||||
if address then
|
||||
local addr = address -- addr is going to be in ipv6 hex (no ipv4)
|
||||
if -- valid ipv6 address?
|
||||
-- select(2, addr:gsub(":",""))==1 -- this shouldn't happen
|
||||
-- 2 ::
|
||||
addr:match"::.+::"
|
||||
-- 3 :::
|
||||
or addr:match":::"
|
||||
-- 4 %x per non [^:] ONLY
|
||||
or addr:match"%x%x%x%x%x"
|
||||
then
|
||||
return nil
|
||||
end
|
||||
local v6,v4 = addr:match("^([%x:]+:)(%d+%.%d+%.%d+%.%d+)$")
|
||||
if v4 and V4Parse(v4) then
|
||||
addr = Format("%s%s:%s", v6, V4ToHex(v4):match"^(....)(....)$")
|
||||
end
|
||||
if addr:gsub(":", "", 7):match":" then return nil end
|
||||
return address, port, addr
|
||||
end
|
||||
end
|
||||
return nil, nil
|
||||
end
|
||||
|
||||
-- Returns ipv6 address filled (0:0:0:0:0) instead of ::
|
||||
local V6Fill = function (addr) -- addr must be hexified
|
||||
-- fill ::
|
||||
if addr:match"::" then
|
||||
local _, count = addr:gsub(":+","")
|
||||
addr = addr:gsub("::"
|
||||
,(addr:match"^::" and "0000:" or ":")
|
||||
.. Rep("0", 8-count,":")
|
||||
,1
|
||||
)
|
||||
end
|
||||
|
||||
-- fill 0
|
||||
addr = addr:gsub("[^:]+"
|
||||
,function (section)
|
||||
return Format("%.4x",tonumber("0x" .. section))
|
||||
end
|
||||
)
|
||||
|
||||
return addr
|
||||
end
|
||||
|
||||
-- cannot return num after fff:ffff:ffff:ffff
|
||||
-- this is dependant on tonumber() itself
|
||||
local V6ToHex = function (addr)
|
||||
local ipv6 = V6Fill(addr)
|
||||
local hex = ipv6:gsub(":","")
|
||||
local num do -- tonumber fails after 3:
|
||||
local x = hex:gsub("^0+", "")
|
||||
if #x<=15 then
|
||||
num = x=="" and 0 or tonumber("0x" .. x)
|
||||
end
|
||||
end
|
||||
return hex, num or -1, ipv6 -- cannot tonumber hex too big
|
||||
end
|
||||
|
||||
-- ipv6_address -> addr?, port?, hex?
|
||||
local V6 = function (address)
|
||||
local addr, port, ipv6 = V6Parse(address)
|
||||
if addr then
|
||||
return addr, port, V6ToHex(ipv6)
|
||||
end
|
||||
return addr, port
|
||||
end
|
||||
|
||||
local IpToHex = function (address)
|
||||
if address:match(ipv4_patt) then
|
||||
return 4, V4(address)
|
||||
end
|
||||
return 6, V6(address)
|
||||
end
|
||||
|
||||
for _, addr in ipairs{
|
||||
"127.0.0.1", "127.0.0.1:80", "::1", "[::1]:80",
|
||||
"2605:2700:0:3::4713:93e3",
|
||||
"[2605:2700:0:3::4713:93e3]:80"
|
||||
} do
|
||||
print(IpToHex(addr))
|
||||
end
|
||||
6
Task/Parse-an-IP-Address/Lua/parse-an-ip-address-2.lua
Normal file
6
Task/Parse-an-IP-Address/Lua/parse-an-ip-address-2.lua
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
4 127.0.0.1 7f000001 2130706433
|
||||
4 127.0.0.1 80 7f000001 2130706433
|
||||
6 ::1 nil 00000000000000000000000000000001 1 0000:0000:0000:0000:0000:0000:0000:0001
|
||||
6 ::1 80 00000000000000000000000000000001 1 0000:0000:0000:0000:0000:0000:0000:0001
|
||||
6 2605:2700:0:3::4713:93e3 nil 260527000000000300000000471393e3 -1 2605:2700:0000:0003:0000:0000:4713:93e3
|
||||
6 2605:2700:0:3::4713:93e3 80 260527000000000300000000471393e3 -1 2605:2700:0000:0003:0000:0000:4713:93e3
|
||||
Loading…
Add table
Add a link
Reference in a new issue