I'd like to have a function that I can pass a whitespace trimmed string to and it will return
0 for error (not a string) 1 for ipv4 2 for ipv6 3 for a string thats not an ip.
Ipv6 has these rules:
Ipv6 is represented by 8 groups of 16-bit hexadecimal values separated by colons (:)
The hexadecimal digits are case-insensitive
Abbreviation rules:
1: Omit leading zeroes in a 16-bit value
2: Replace one or more groups of consecutive zeroes by a double colon
wiki example showing 3 ways that are all the same ipv6:
fe80:0000:0000:0000:0202:b3ff:fe1e:8329
fe80:0:0:0:202:b3ff:fe1e:8329
fe80::202:b3ff:fe1e:8329
I'm reasonably sure for ipv4 you just check for three . then check the string is all
numbers and the .'s are counted as numbers and the last check for just a string
would be at the end of an if statement so if its not ipv4/6 and its a string then
it returns 3
there is a function in lua called type, you can use it like type (value) == "number" and this will only be true if value is a number. if this solved your problem you should not be asking "how to check wether a value is a string" as you obviously wanted to know wether a string contains a digit. if that solved your problem.
If the given string S is a valid IPv4, then print “IPv4”, if the string S is a valid IPv6, then print “IPv4”. Otherwise, print “-1”. A valid IPv4 address is an IP in the form “x 1.x 2.x 3.x 4 ” where 0 ≤ x i ≤ 255 and x i cannot contain leading zeros.
If statement in Lua is just like other programming languages including C, C++, Python. If a statement is very important while programming as it leverages the option of creating a condition where the coder can derive two outputs for the true and false results respectively. In this article, if the statement is explained in detail with examples.
A valid IPv6 address is an IP in the form “x 1 : x 2 : x 3 : x 4 : x 5 : x 6 : x 7 : x 8 ” where: x i is a hexadecimal string which may contain digits, lower-case English letter (‘a’ to ‘f’) and upper-case English letters (‘A’ to ‘F’).
Mike's solution is good, but it can be improved on in several ways. In its current form it doesn't get to ipv6 address check, but it's easy to fix. The ipv6 check fails on things like "1050!0!0+0-5@600$300c#326b"
and "1050:0:0:0:5:600:300c:326babcdef"
(recognizing both as valid addresses) and "1050:::600:5:1000::"
(recognizing it as string).
Here is the improved version (IPv4 are assumed to be decimal numbers and IPv6 are assumed to be hexadecimal numbers):
function GetIPType(ip)
local R = {ERROR = 0, IPV4 = 1, IPV6 = 2, STRING = 3}
if type(ip) ~= "string" then return R.ERROR end
-- check for format 1.11.111.111 for ipv4
local chunks = {ip:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)$")}
if #chunks == 4 then
for _,v in pairs(chunks) do
if tonumber(v) > 255 then return R.STRING end
end
return R.IPV4
end
-- check for ipv6 format, should be 8 'chunks' of numbers/letters
-- without leading/trailing chars
-- or fewer than 8 chunks, but with only one `::` group
local chunks = {ip:match("^"..(("([a-fA-F0-9]*):"):rep(8):gsub(":$","$")))}
if #chunks == 8
or #chunks < 8 and ip:match('::') and not ip:gsub("::","",1):match('::') then
for _,v in pairs(chunks) do
if #v > 0 and tonumber(v, 16) > 65535 then return R.STRING end
end
return R.IPV6
end
return R.STRING
end
The script to check:
local IPType = {[0] = "Error", "IPv4", "IPv6", "string"}
local ips = {
"128.1.0.1", -- ipv4
"223.255.254.254", -- ipv4
"999.12345.0.0001", -- invalid ipv4
"1050:0:0:0:5:600:300c:326b", -- ipv6
"1050!0!0+0-5@600$300c#326b", -- string
"1050:0:0:0:5:600:300c:326babcdef", -- string
"1050:0000:0000:0000:0005:0600:300c:326b", -- ipv6
"fe80:0000:0000:0000:0202:b3ff:fe1e:8329", -- ipv6
"fe80:0:0:0:202:b3ff:fe1e:8329", -- ipv6
"fe80::202:b3ff:fe1e:8329", -- ipv6
"1050:::600:5:1000::", -- contracted ipv6
"::", -- ipv6
"::1", -- ipv6
"::1::", -- string
"129.garbage.9.1", -- string
"xxx127.0.0.0", -- error
"xxx1050:0000:0000:0000:0005:0600:300c:326b", -- string
129.10 -- error
}
for k,v in pairs(ips) do
print(v, IPType[GetIPType(v)])
end
And the output:
128.1.0.1 IPv4
223.255.254.254 IPv4
999.12345.0.0001 string
1050:0:0:0:5:600:300c:326b IPv6
1050!0!0+0-5@600$300c#326b string
1050:0:0:0:5:600:300c:326babcdef string
1050:0000:0000:0000:0005:0600:300c:326b IPv6
fe80:0000:0000:0000:0202:b3ff:fe1e:8329 IPv6
fe80:0:0:0:202:b3ff:fe1e:8329 IPv6
fe80::202:b3ff:fe1e:8329 IPv6
1050:::600:5:1000:: IPv6
:: IPv6
::1 IPv6
::1:: string
129.garbage.9.1 string
xxx127.0.0.0 string
xxx1050:0000:0000:0000:0005:0600:300c:326b string
129.1 Error
Updated on 9/6/2018 to add handling of garbage before/after addresses and checking for contracted ipv6, which allows for fewer than 8 groups with one empty group of two consecutive colons.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With