Modul:IPAddress: Forskjell mellom sideversjoner

Fra Wikisida.no
Hopp til navigering Hopp til søk
m (Én sideversjon ble importert)
m (7 sideversjoner ble importert fra en:Module:IPAddress)
Linje 1: Linje 1:
local p = {}
--[=[
Functions are not "local", so other modules can require this module and call them directly.
We return an object with 3 small stub functions to call the real ones so that the functions
can be called from templates also.


function p._isIpV6(s)
Only [[dotted decimal]] notation for IPv4 supported. Does not support
local dcolon, groups
dotted hexadecimal, dotted octal, or single-number formats (see [[IPv4#Address_representations]]).
if type(s) ~= "string"
or s:len() == 0
or s:find("[^:%x]") -- only colon and hex digits are legal chars
or s:find("^:[^:]") -- can begin or end with :: but not with single :
or s:find("[^:]:$")
or s:find(":::")
then
return false
end
s, dcolon = s:gsub("::", ":")
if dcolon > 1 then return false end -- at most one ::
s = s:gsub("^:?", ":") -- prepend : if needed, upper
s, groups = s:gsub(":%x%x?%x?%x?", "") -- remove valid groups, and count them
return ( (dcolon == 1 and groups < 8) or (dcolon == 0 and groups == 8) )
and ( s:len() == 0 or (dcolon == 1 and s == ":") ) -- might be one dangling : if original ended with ::
end


function p._isIpV4(s)
Unit tests at Module:IPAddress/tests
local function legal(n) return (tonumber(n) or 256) < 256 and not n:match("^0%d") end
]=]
if type(s) ~= "string" then return false end
local p1, p2, p3, p4 = s:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)$")
return legal(p1) and legal(p2) and legal(p3) and legal(p4)
end


function _isIpV6( s )
function p._isIp(s)
return p._isIpV4(s) and "4" or p._isIpV6(s) and "6"
local dcolon, groups
if type( s ) ~= "string"
or s:len() == 0
or s:find( "[^:%x]" ) -- only colon and hex digits are legal chars
or s:find( "^:[^:]" ) -- can begin or end with :: but not with single :
or s:find( "[^:]:$" )
or s:find( ":::" )
then
return false
end
s, dcolon = s:gsub( "::", ":" )
if dcolon > 1 then return false end -- at most one ::
s = s:gsub( "^:?", ":" ) -- prepend : if needed, upper
s, groups = s:gsub( ":%x%x?%x?%x?", "" ) -- remove valid groups, and count them
return ( ( dcolon == 1 and groups < 8 ) or ( dcolon == 0 and groups == 8 ) )
and ( s:len() == 0 or ( dcolon == 1 and s == ":" ) ) -- might be one dangling : if original ended with ::
end
end


function _isIpV4( s )
function p._isIpV4Range(s)
return p._isIpV4(s:gsub("/%d+$", "")) and (p._isIpOrRange(s) == 'range')
local function legal( n ) return ( tonumber( n ) or 256 ) < 256 and not n:match("^0%d") end-- in lua 0 is true!
if type( s ) ~= "string" then return false end
local p1, p2, p3, p4 = s:match( "^(%d+)%.(%d+)%.(%d+)%.(%d+)$" )
return legal( p1 ) and legal( p2 ) and legal( p3 ) and legal( p4 )
end
end


function _isIp( s )
function p._isIpV6Range(s)
return _isIpV4( s ) and "4" or _isIpV6( s ) and "6"
return p._isIpV6(s:gsub("/%d+$", "")) and (p._isIpOrRange(s) == 'range')
end
end


function p._isIpOrRange(s)
local p = {}
local modip = require('Module:IP')
local success, ip = pcall(modip.IPAddress.new, s)
if success then
return 'ip'
end
success, ip = pcall(modip.Subnet.new, s)
if success then
return 'range'
end
return ''
end


local function input(frame)
function p.isIpV6(frame) return _isIpV6( frame.args[ 1 ] ) and "1" or "0" end
-- Return input parameter after replacing any of following directional markers.
function p.isIpV4(frame) return _isIpV4( frame.args[ 1 ] ) and "1" or "0" end
-- LRM : LEFT-TO-RIGHT MARK (U+200E) : hex e2 80 8e = 226 128 142
function p.isIp(frame) return _isIp( frame.args[ 1 ] ) or "" end
-- LRE : LEFT-TO-RIGHT EMBEDDING (U+202A) : hex e2 80 aa = 226 128 170
-- PDF : POP DIRECTIONAL FORMATTING (U+202C) : hex e2 80 ac = 226 128 172
-- This is required for MediaWiki:Blockedtext message.
return (frame.args[1] or ''):gsub('\226\128[\142\170\172]', ' ') -- replace LRM, LRE, PDF with space delimiter
end

function p.isIpV6(frame) return p._isIpV6(input(frame)) and "1" or "0" end
function p.isIpV4(frame) return p._isIpV4(input(frame)) and "1" or "0" end
function p.isIpV6Range(frame) return p._isIpV6Range(input(frame)) and "1" or "0" end
function p.isIpV4Range(frame) return p._isIpV4Range(input(frame)) and "1" or "0" end
function p.isIp(frame) return p._isIp(input(frame)) or "" end

function p.isIpOrRange(frame)
-- {{#invoke:IPAddress|isIpOrRange|x}} → 'ip' (IPv4/IPv6) or 'range' (CIDR IPv4/IPv6) or '' (invalid)
return p._isIpOrRange(input(frame))
end


return p
return p

Sideversjonen fra 18. sep. 2024 kl. 18:34

Denne modulen inneholder noen funksjoner for sjekke om en streng er en IP-adresse (enten IPv4 eller IPv6).
Modulen brukes fra malen {{ErIPAdresse}}. Siden funksjonene ikke er lokale kan modulen også brukes direkte fra andre moduler.

Oversikt

isIp

Tar en streng som argument og returnerer:

  • "6" dersom strengen er en gyldig IPv6-adresse
  • "4" dersom strengen er en gyldig IPv4-adresse
  • tom streng dersom ikke en gyldig IP-adresse

Legg merke til at ekstra whitespace blir ikke godtatt (f.eks. blir ikke "127.0.0.1 " med et ekstra mellomrom på slutten gjenkjent som en IP-adresse).

isIpV6

Returner 1 dersom strengen er en gyldig IPv6-adresse, ellers 0.

isIpV4

Returner 1 dersom strengen er en gyldig IPv4-adresse, ellers 0.


local p = {}

function p._isIpV6(s)
	local dcolon, groups
	if type(s) ~= "string"
		or s:len() == 0
		or s:find("[^:%x]") -- only colon and hex digits are legal chars
		or s:find("^:[^:]") -- can begin or end with :: but not with single :
		or s:find("[^:]:$")
		or s:find(":::")
	then
		return false
	end
	s, dcolon = s:gsub("::", ":")
	if dcolon > 1 then return false end -- at most one ::
	s = s:gsub("^:?", ":") -- prepend : if needed, upper
	s, groups = s:gsub(":%x%x?%x?%x?", "") -- remove valid groups, and count them
	return ( (dcolon == 1 and groups < 8) or (dcolon == 0 and groups == 8) )
		and ( s:len() == 0 or (dcolon == 1 and s == ":") ) -- might be one dangling : if original ended with ::
end

function p._isIpV4(s)
	local function legal(n) return (tonumber(n) or 256) < 256  and not n:match("^0%d") end
	if type(s) ~= "string" then return false end
	local p1, p2, p3, p4 = s:match("^(%d+)%.(%d+)%.(%d+)%.(%d+)$")
	return legal(p1) and legal(p2) and legal(p3) and legal(p4)
end

function p._isIp(s)
	return p._isIpV4(s) and "4" or p._isIpV6(s) and "6"
end

function p._isIpV4Range(s)
	return p._isIpV4(s:gsub("/%d+$", "")) and (p._isIpOrRange(s) == 'range')
end

function p._isIpV6Range(s)
	return p._isIpV6(s:gsub("/%d+$", "")) and (p._isIpOrRange(s) == 'range')
end

function p._isIpOrRange(s)
	local modip = require('Module:IP')
	local success, ip = pcall(modip.IPAddress.new, s)
	if success then
		return 'ip'
	end
	success, ip = pcall(modip.Subnet.new, s)
	if success then
		return 'range'
	end
	return ''
end

local function input(frame)
	-- Return input parameter after replacing any of following directional markers.
	-- LRM : LEFT-TO-RIGHT MARK (U+200E)         : hex e2 80 8e = 226 128 142
	-- LRE : LEFT-TO-RIGHT EMBEDDING (U+202A)    : hex e2 80 aa = 226 128 170
	-- PDF : POP DIRECTIONAL FORMATTING (U+202C) : hex e2 80 ac = 226 128 172
	-- This is required for MediaWiki:Blockedtext message.
	return (frame.args[1] or ''):gsub('\226\128[\142\170\172]', ' ')  -- replace LRM, LRE, PDF with space delimiter
end

function p.isIpV6(frame) return p._isIpV6(input(frame)) and "1" or "0" end
function p.isIpV4(frame) return p._isIpV4(input(frame)) and "1" or "0" end
function p.isIpV6Range(frame) return p._isIpV6Range(input(frame)) and "1" or "0" end 
function p.isIpV4Range(frame) return p._isIpV4Range(input(frame)) and "1" or "0" end 
function p.isIp(frame) return p._isIp(input(frame)) or "" end

function p.isIpOrRange(frame)
	-- {{#invoke:IPAddress|isIpOrRange|x}} → 'ip' (IPv4/IPv6) or 'range' (CIDR IPv4/IPv6) or '' (invalid)
	return p._isIpOrRange(input(frame))
end

return p