יחידה:קוד מזהה

מתוך ויקימסע

ניתן ליצור תיעוד על היחידה הזאת בדף יחידה:קוד מזהה/תיעוד

function checkisbn( frame )
	local isbn_str = frame.args[1]
	if nil ~= isbn_str:match("[^%s-0-9X]") then
		return false
	end		-- fail if isbn_str contains anything but digits, hyphens, or the uppercase X
	isbn_str = isbn_str:gsub( "-", "" ):gsub( " ", "" );	-- remove hyphens and spaces
	local len = isbn_str:len();
 
	if len ~= 10 and len ~= 13 then
		return false;
	end

	if len == 10 then
		if isbn_str:match( "^%d*X?$" ) == nil then
			return false
		end
		return is_valid_isbn(isbn_str, 10)
	else
		local temp = 0
		if isbn_str:match( "^97[89]%d*$" ) == nil
			then return false
		end	-- isbn13 begins with 978 or 979
		isbn_str = { isbn_str:byte(1, len) }
		for i, v in ipairs( isbn_str ) do
			temp = temp + (3 - 2*(i % 2)) * tonumber( string.char(v) )
		end
		return temp % 10 == 0
	end
end

function is_valid_isbn (isxn_str, len)
	local temp = 0
	isxn_str = { isxn_str:byte(1, len) }	-- make a table of bytes
	len = len + 1;							-- adjust to be a loop counter
	for i, v in ipairs( isxn_str ) do		-- loop through all of the bytes and calculate the checksum
		if v == string.byte( "X" ) then		-- if checkdigit is X
			temp = temp + 10*( len - i )	-- it represents 10 decimal
		else
			temp = temp + tonumber( string.char(v) ) * (len - i)
		end
	end
	return temp % 11 == 0					-- returns true if calculation result is zero
end

function pmid(frame)
	return check(frame.args[1], 30000000)
end

function rfc(frame)
	return check(frame.args[1], 10000)
end

function check(id, test_limit)
	if id:match("[^%d]") then							-- if id has anything but digits
		return false
	else
		local id_num = tonumber(id)						-- convert id to a number for range testing
		if 1 > id_num or test_limit < id_num then		-- if id is outside test limit boundaries
			return false
		end
	end
	
	return true
end

-- The code taken from Module:Citation/CS1 and changed

return {isbn = checkisbn, pmid = pmid, rfc = rfc}