--驗證身份證信息 --只支持18位身份證的驗證 --[[ #身份證18位編碼規則:dddddd yyyymmdd xxx y #dddddd:地區碼 #yyyymmdd: 出生年月日 #xxx:順序類編碼,無法確定,奇數為男,偶數為女 #y: 校驗碼,該位數值可通過前17位計算獲得 #<p /> #18位號碼加權因子為(從右到左) Wi = [ 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2,1 ] #驗證位 Y = [ 1, 0, 10, 9, 8, 7, 6, 5, 4, 3, 2 ] #校驗位計算公式:Y_P = mod( ∑(Ai×Wi),11 ) #i為身份證號碼從右往左數的 2...18 位; Y_P為腳丫校驗碼所在校驗碼數組位置 參考代碼: https://github.com/yujinqiu/idlint ]] local string_len = string.len local tonumber = tonumber -- // wi =2(n-1)(mod 11) local wi = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 }; -- // verify digit local vi= { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' }; local function isBirthDate(date) local year = tonumber(date:sub(1,4)) local month = tonumber(date:sub(5,6)) local day = tonumber(date:sub(7,8)) if year < 1900 or year > 2100 or month >12 or month < 1 then return false end -- //月份天數表 local month_days = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; local bLeapYear = (year % 4 == 0 and year % 100 ~= 0) or (year % 400 == 0) if bLeapYear then month_days[2] = 29; end if day > month_days[month] or day < 1 then return false end return true end local function isAllNumberOrWithXInEnd( str ) local ret = str:match("%d+X?") return ret == str end local function checkSum(idcard) -- copy from http://stackoverflow.com/questions/829063/how-to-iterate-individual-characters-in-lua-string local nums = {} local _idcard = idcard:sub(1,17) for ch in _idcard:gmatch"." do table.insert(nums,tonumber(ch)) end local sum = 0 for i,k in ipairs(nums) do sum = sum + k * wi[i] end return vi [sum % 11+1] == idcard:sub(18,18 ) end local err_success = 0 local err_length = 1 local err_province = 2 local err_birth_date = 3 local err_code_sum = 4 local err_unknow_charactor = 5 local function verifyIDCard(idcard) if string_len(idcard) ~= 18 then return err_length end if not isAllNumberOrWithXInEnd(idcard) then return err_unknow_charactor end -- //第1-2位為省級行政區划代碼,[11, 65] (第一位華北區1,東北區2,華東區3,中南區4,西南區5,西北區6) local nProvince = tonumber(idcard:sub(1, 2)) if( nProvince < 11 or nProvince > 65 ) then return err_province end -- //第3-4為為地級行政區划代碼,第5-6位為縣級行政區划代碼因為經常有調整,這塊就不做校驗 -- //第7-10位為出生年份;//第11-12位為出生月份 //第13-14為出生日期 if not isBirthDate(idcard:sub(7,14)) then return err_birth_date end if not checkSum(idcard) then return err_code_sum end return err_success end local function UnitTest_CheckBirthDay() assert(isBirthDate('19881128') == true) assert(isBirthDate('19881328') == false) assert(isBirthDate('19881232') == false) assert(isBirthDate('19880229') == true) assert(isBirthDate('19880228') == true) assert(isBirthDate('18000228') == false) assert(isBirthDate('20000229') == true) assert(isBirthDate('21220228') == false) end local function UnitTest() print('begin UnitTest') UnitTest_CheckBirthDay() assert(verifyIDCard('411302198011276412') == err_code_sum) assert(verifyIDCard('4113021988112864x7') == err_unknow_charactor) assert(verifyIDCard('41130219881128641') == err_length) end UnitTest()
手游項目中需要實名需求,項目是lua寫的,github上找了下沒有找到lua的實現,只看到了c++,python,js.於是仿照其中的c++,移植到lua.