lua身份证号码验证~

--验证身份证信息
--只支持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.

时间: 2024-11-05 11:28:37

lua身份证号码验证~的相关文章

C#实现身份证号码验证的方法

本文实例讲述了C#实现身份证号码验证的方法.分享给大家供大家参考.具体实现方法如下: 随着现在互联网的发展,越来越多的注册用户的地方都用到了身份证,那么对于输入的身份证如何验证呢?看下面的代码,其实很简单. 主要注意的是,目前的身份证分为16和18位,然后分别验证校验位,省份,生日即可. 主要类如下: /// <summary> /// 验证身份证号码类 /// </summary> public class IDCardValidation { /// <summary&g

javascript身份证号码验证

https://github.com/oxcow/id-number-validator 版权声明: 关于<javascript身份证号码验证>的一切权利归作者@Leeyee所有: 非商用.非衍生; 如需转载需要注明来源于http://iyiguo.net/blog/2013/07/31/javascript-idcard-validate/ 15位身份证号码编码规则 18位身份证号码编码规则 校验规则 javascript编码实现 源代码 验证示例 15位身份证号码编码规则 ddddddyy

编程乐趣:身份证号码验证的方法

随着如今互联网的发展,越来越多的注冊用户的地方都用到了身份证.那么对于输入的身份证怎样验证呢?看以下的代码,事实上非常easy.主要注意的是,眼下的身份证分为16和18位,然后分别验证校验位.省份,生日就可以.主要类: /// <summary> /// 验证身份证号码类 /// </summary> public class IDCardValidation { /// <summary> /// 验证身份证合理性 /// </summary> /// &

js正则实现二代身份证号码验证详解

js正则实现二代身份证号码验证详解 根据[中华人民共和国国家标准 GB 11643-1999]中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成.排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码. 地址码表示编码对象常住户口所在县(市.旗.区)的行政区划代码. 出生日期码表示编码对象出生的年.月.日,其中年份用四位数字表示,年.月.日之间不用分隔符. 顺序码表示同一地址码所标识的区域范围内,对同年.月.日出生的人员

身份证号码验证正则表达式及用法(包括:位数、规则等)

//sfz.js页面function CheckIDCard(StrNumber) { //判断身份证号码格式函数 //公民身份号码是特征组合码, //排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码 //身份证号码长度判断 if(StrNumber.length<15||StrNumber.length==16||StrNumber.length==17||StrNumber.length>18) { return {"code"

身份证号码验证及其相关!

2015-11-16 16:35:32 小写转大写:toUpper(); 大写转小写:toLower(); 替换:Replace('X','Y'); 将字符串转换为字符数组:toCharArray(); 从X处取出Y个字符:string.Substring(ing x,int y); 在X处插入Y:string.Insert(int X,string Y); 用x分割:string.Split('x'); 验证18位身份证号(包含小写x): 1 /// <summary> 2 /// 18位身

身份证号码验证

<head> <title>身份证号码验证</title> <meta charset="utf-8"/> <script type="text/javascript"> var vcity={ 11:"北京",12:"天津",13:"河北",14:"山西",15:"内蒙古", 21:"辽宁&quo

15/18位身份证号码验证的正则表达式总结(详细版)

前言 开发过程中,常常需要对一些输入信息进行有效性验证,使用正则表达式进行校验是最简单.效率最高的方式了,下面就来看看15/18位身份证号码验证的正则表达式吧. 介绍 xxxxxx yyyy MM dd 375 0     十八位 xxxxxx    yy MM dd   75 0     十五位 地区: [1-9]\d{5} 年的前两位: (18|19|([23]\d))            1800-2399 年的后两位: \d{2} 月份: ((0[1-9])|(10|11|12)) 天

js实现身份证号码验证

/*根据[中华人民共和国国家标准 GB 11643-1999]中有关公民身份号码的规定,公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成.排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码.地址码表示编码对象常住户口所在县(市.旗.区)的行政区划代码.出生日期码表示编码对象出生的年.月.日,其中年份用四位数字表示,年.月.日之间不用分隔符.顺序码表示同一地址码所标识的区域范围内,对同年.月.日出生的人员编定的顺序号.顺序码的奇数分给男性,偶