Advertisement
uriid1

E-mail validator | Lua 5.1+, LuaJit

Oct 1st, 2022 (edited)
1,054
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 5.04 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.     str = str:lower()
  17.     local re_local_part = '([a-z0-9%.!#%$%%&\'%*%+%-/=%?^_`{|}~%(%) "]+)'
  18.     local re_domain = '([a-z0-9%(%)%-%.:%[%]]+)'
  19.     local local_part, domain = str:match('^'..re_local_part..'@'..re_domain..'$')
  20.  
  21.     -- Check exists local-part and domain
  22.     if not local_part or not domain then
  23.         return false, 'Invalid local-part or domain name'
  24.     end
  25.  
  26.     -- Check length
  27.     if #local_part > 64 then
  28.         return false, 'Local-part over 64 symbol'
  29.     elseif #domain > 255 then
  30.         return false, 'Domain over 255 symbol'
  31.     end
  32.        
  33.     -- Check local-part in quotes
  34.     local text_in_quotes = local_part:match('^"(.+)"$')
  35.     if text_in_quotes then
  36.         if text_in_quotes:match('[^a-z0-9!#$%%&\'%*%+%-/=%?^_ `{|}~%.]') then
  37.            return false, 'Invalid characters in quotes local_part'
  38.         end
  39.     else
  40.         if local_part:find('"') then
  41.             return false, 'Invalid character " in local-part'
  42.         end
  43.     end
  44.  
  45.     -- Check comment
  46.     local comment_in_local_part = local_part:match('(%(.+%))')
  47.     if comment_in_local_part then
  48.         local some_text, count_char = comment_in_local_part:gsub('[()]', '')
  49.         if count_char > 2 then
  50.             return false, 'Multiple comment in local-part are not allowed'
  51.         end
  52.         local_part = local_part:gsub('%('..some_text..'%)', '')
  53.     end
  54.  
  55.     local comment_in_domain = domain:match('(%(.+%))')
  56.     if comment_in_domain then
  57.         local some_text, count_char = comment_in_domain:gsub('[()]', '')
  58.         if count_char > 2 then
  59.             return false, 'Multiple comment in domain are not allowed'
  60.         end
  61.         domain = domain:gsub('%('..some_text..'%)', '')
  62.     end
  63.  
  64.     -- Check [] characters in local-part
  65.     if local_part:match('%[.+%]') then
  66.         return false, 'Invalid local-part, characters []'
  67.     end
  68.  
  69.     -- Check correct local-part
  70.     if local_part:find("%.%.") or
  71.        local_part:find("%-%-") or
  72.        local_part:find("%+%+") then
  73.         return false, 'Too many periods in local-part'
  74.     end
  75.  
  76.     -- Dot pos check in local-part
  77.     if local_part:sub(1, 1) == '.' then
  78.         return false, 'Dot cannot be the first character'
  79.     elseif local_part:sub(-1) == '.' then
  80.         return false, 'Dot cannot be the last character'
  81.     end
  82.  
  83.     -- DNS domain check
  84.     local hostname = domain:match('^[%d%a%-%.]+$')
  85.     if hostname then
  86.         if domain:sub(0, 1) == '.' or
  87.            domain:sub(-1) == '.'   or
  88.            domain:find('%.%.')
  89.         then
  90.             return false, 'Invalid domain name'
  91.         end
  92.     end
  93.  
  94.     -- IpV4
  95.     local ipv4 = domain:match('^%[(.+)%]$')
  96.     if ipv4 then
  97.         local a, b, c, d = domain:match('(%d+)%.(%d+)%.(%d+)%.(%d+)')
  98.         if a and b and c and d then
  99.             if not ((tonumber(a) < 256) and
  100.                     (tonumber(b) < 256) and
  101.                     (tonumber(c) < 256) and
  102.                     (tonumber(d) < 256))
  103.             then
  104.                 return false, 'Invalid ipV4 domain'
  105.             end
  106.         end
  107.     end
  108.  
  109.     -- ipV6
  110.     local ipv6 = domain:match('^%[ipv6:(.-)%]$')
  111.     if ipv6 then
  112.         if not ipv6:find('^[a-f0-9]+'..(':[a-f0-9]+'):rep(7)..'$') then
  113.             return false, 'Invalid IPv6 domain'
  114.         end
  115.     end
  116.  
  117.     return true
  118. end
  119.  
  120.  
  121. -- Test
  122. print('[-- Valid --]')
  123. local valid = {
  124.     'appdurov@domain.co.tk';
  125.     'disposable.style.email.with+symbol@example.com';
  126.     'very.common@example.com';
  127.     'simple@[127.128.0.255]';
  128.     'postmaster@[IPv6:2001:0db8:85a3:0000:0000:8a2e:0370:7334]';
  129.     'postmaster(coment)@domain.lol';
  130.     'postmaster@(comment)domain.lol';
  131. }
  132.  
  133. for i = 1, #valid do
  134.     local res, err = email_validator(valid[i])
  135.     if res then
  136.         print('Test:', i, res)
  137.     else
  138.         print('Test:', i, res, valid[i], err)
  139.     end
  140. end
  141.  
  142.  
  143. print('\n[-- Invalid --]')
  144. local invalid = {
  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, #invalid do
  162.     local res, err = email_validator(invalid[i])
  163.     if not res then
  164.         print('Test:', i, res)
  165.     else
  166.         print('Test:', i, res, invalid[i], err)
  167.     end
  168. end
Tags: lua
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement