Advertisement
uriid1

E-mail validator | Lua

Oct 1st, 2022
936
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.00 KB | None | 0 0
  1. --[[
  2.     ####--------------------------------####
  3.     #--# Author:   by uriid1            #--#
  4.     #--# License:  GNU GPLv3            #--#
  5.     #--# Telegram: @main_moderator      #--#
  6.     #--# E-mail:   appdurov@gmail.com   #--#
  7.     ####--------------------------------####
  8. --]]
  9.  
  10. local function email_validator(str)
  11.     if type(str) ~= 'string' then
  12.         return false, 'E-mail is not a string'
  13.     end
  14.  
  15.     -- Capture
  16.     local local_part, domain = str:lower():match('^([A-z0-9.!#$%&\'*+-/=?^_`{|}~() "]+)@([()A-z0-9-.:]+)$')
  17.  
  18.     -- Check exists local-part and domain
  19.     if (not local_part) or (not domain) then
  20.         return false, 'Invalid local-part or domain name'
  21.     end
  22.  
  23.     -- Check length
  24.     if #local_part > 63 then
  25.         return false, 'Local-part over 64 symbol'
  26.     elseif #domain > 255 then
  27.         return false, 'Domain over 255 symbol'
  28.     end
  29.        
  30.     -- Check local-part in quotes
  31.     local text_in_quotes = local_part:match('^"(.+)"$')
  32.     if text_in_quotes then
  33.         if text_in_quotes:match('[^A-z!#$%&\'*+-/=?^_ `{|}~.0-9]') then
  34.            return false, 'Invalid characters in quotes local_part'
  35.         end
  36.     else
  37.         if local_part:find('"') then
  38.             return false, 'Invalid character " in local-part'
  39.         end
  40.     end
  41.  
  42.     -- Check comment
  43.     local comment_in_local_part = local_part:match('(%(.+%))')
  44.     local comment_in_domain     = domain:match('(%(.+%))')
  45.  
  46.     if comment_in_local_part then
  47.         local some_text, count_char = comment_in_local_part:gsub('[()]', '')
  48.         if count_char > 2 then
  49.             return false, 'Multiple comment in local-part are not allowed'
  50.         end
  51.         local_part = local_part:gsub('%('..some_text..'%)', '')
  52.     end
  53.  
  54.     if comment_in_domain then
  55.         local some_text, count_char = comment_in_domain:gsub('[()]', '')
  56.         if count_char > 2 then
  57.             return false, 'Multiple comment in domain are not allowed'
  58.         end
  59.         domain = domain:gsub('%('..some_text..'%)', '')
  60.     end
  61.  
  62.     -- Check [] characters in local-part
  63.     if local_part:match('%[.+%]') then
  64.         return false, 'Invalid local-part, characters []'
  65.     end
  66.  
  67.     -- Check correct local-part
  68.     if local_part:find("%.%.") or
  69.        local_part:find("%-%-") or
  70.        local_part:find("%+%+") then
  71.         return false, 'Too many periods in local-part'
  72.     end
  73.  
  74.     -- Dot pos check in local-part
  75.     if local_part:sub(1, 1) == '.' then
  76.         return false, 'Dot cannot be the first character'
  77.     elseif local_part:sub(-1) == '.' then
  78.         return false, 'Dot cannot be the last character'
  79.     end
  80.  
  81.     -- DNS domain check
  82.     local hostname = domain:match('^[%d%a-.]+$')
  83.     if hostname then
  84.         if domain:sub(0, 1) == '.' or
  85.            domain:sub(-1) == '.'   or
  86.            domain:find('%.%.')
  87.         then
  88.             return false, 'Invalid domain name'
  89.         end
  90.     end
  91.  
  92.     -- IpV4 domain check
  93.     local ipv4 = domain:match('^%[.+%]$')
  94.     if ipv4 then
  95.         local a, b, c, d = domain:match('%[(%d+)%.(%d+)%.(%d+)%.(%d+)%]')
  96.         -- Is ipv4
  97.         if a and b and c and d then
  98.             a, b, c, d = tonumber(a), tonumber(b), tonumber(c), tonumber(d)
  99.             if not ((a < 256) and
  100.                     (b < 256) and
  101.                     (c < 256) and
  102.                     (d < 256))
  103.             then
  104.                 return false, 'Invalid ipV4 domain'
  105.             end
  106.         end
  107.     end
  108.  
  109.     -- ipV6 domain check
  110.     local ipv6 = domain:match('^%[ipv6:(.+)%]$')
  111.     if ipv6 then
  112.         -- Is ipv6
  113.         if not ipv4:find(('([a-fA-F0-9]+):'):rep(7)..'([a-fA-F0-9]+)') then
  114.             return false, 'Invalid IPv6 domain'
  115.         end
  116.     end
  117.  
  118.     return (hostname or ipv4 or ipv6) and true or false
  119. end
  120.  
  121.  
  122. -- Test
  123. print('Valid Test')
  124. local valid = {
  125.     'appdurov@domain.co.tk';
  126.     'disposable.style.email.with+symbol@example.com';
  127.     'very.common@example.com';
  128.     'simple@[127.0.0.255]';
  129.     'postmaster@[IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:7334]';
  130.     'postmaster(coment)@domain.lol';
  131.     'postmaster@(comment)domain.lol';
  132. }
  133.  
  134. for i = 1, #valid do
  135.     if email_validator(valid[i]) then
  136.         print('Test: '..i, 'True')
  137.     else
  138.         print('Test: '..i, 'Failed')
  139.     end
  140. end
  141.  
  142. --
  143. print('\nNot Valid Test')
  144. local not_valid = {
  145.     'blablabla';
  146.     '   appdurov@gmail.com ';
  147.     '.John.Doe@example.com';
  148.     'John.Doe.@example.com';
  149.     'Abc.example.com';
  150.     'A@b@c@example.com';
  151.     'a"b(c)d,e:f;g<h>i[j\\k]l@example.com';
  152.     'just"not"right@example.com';
  153.     'this is"not\allowed@example.com';
  154.     'this\\ still\\"not\\allowed@example.com';
  155.     '1234567890123456789012345678901234567890123456789012345678901234+x@example.com';
  156.     'i_like_underscore@but_its_not_allowed_in_this_part.example.com';
  157.     'QA[icon]CHOCOLATE[icon]@test.com';
  158.     '[]!@#$%^&@gmail.com';
  159. }
  160.  
  161. for i = 1, #not_valid do
  162.     if not email_validator(not_valid[i]) then
  163.         print('Test: '..i, 'True')
  164.     else
  165.         print('Test: '..i, 'Failed')
  166.     end
  167. end
Tags: lua
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement