Lua function check if ipv4 or ipv6 or string

ip-address, ipv4, ipv6, lua, pattern-matching

Solution

this seems like a pretty basic problem to solve. i think this function does what you need...

function GetIPType(ip)
    -- must pass in a string value
    if ip == nil or type(ip) ~= "string" then
        return 0
    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) < 0 or tonumber(v) > 255) then
                return 0
            end
        end
        return 1
    else
        return 0
    end

    -- check for ipv6 format, should be 8 'chunks' of numbers/letters
    local _, chunks = ip:gsub("[%a%d]+%:?", "")
    if chunks == 8 then
        return 2
    end

    -- if we get here, assume we've been given a random string
    return 3
end

tested it with this code:

local IPType = {
    [0] = "Error",
    [1] = "IPv4",
    [2] = "IPv6",
    [3] = "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:0000:0000:0000:0005:0600:300c:326b",  -- ipv6
    "1050:::600:5:1000::",  -- contracted ipv6
    "129.garbage.9.1",  -- string
    129.10              -- error
}

for k,v in pairs(ips) do
    print(v, IPType[GetIPType(v)])
end

which generated this output:

128.1.0.1   IPv4
223.255.254.254 IPv4
1050:0:0:0:5:600:300c:326b  IPv6
1050:0000:0000:0000:0005:0600:300c:326b IPv6
129.garbage.9.1 string
129.1   Error

in the future, you'll get more helpful feedback if you actually post the code you've attempted to write to solve your particular problem, and let us know where you need help. SO isn't a personal code writing service, as stated in the faq. however, i'll give you the benefit of the doubt since you look new and this is something that could potentially benefit other people. the code above is basic, so feel free to update it if it doesn't catch fringe test cases i don't know about.

Problem

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

Original source

Related problems