PB函数验证身份证正确性及合法性

PB函数:

`Powerbuilder校验身份证:

  • 函数名称:Boolean gf_check_sfzh(string as_identity)
  • 函数功能:验证身份证号输入的正确性(可以对身份证号码的第18位校验位进行判断.)
/*-------------------------------------------------------------------------------
* 函数名称:Boolean gf_check_sfzh(string as_identity)
* 函数功能:验证身份证号输入的正确性(可以对身份证号码的第18位校验位进行判断.)

* 参数说明:string    as_identity    身份证号

* 返 回 值:True  成功
*           False 失败

* gf_check_sfzh('身份证号')  

* 修改日期:2023-12-20

*--------------------------------------------------------------------------------*/

//定义变量
string ls_identity_no                    //传入的身份证号
string ls_year,ls_month,ls_day,ls_date   //身份证号的生日(年、月、日、日期)
string ls_today                          //今天的日期
string ls_area                           //区域
long ll_year                             //年
long ll_identity_no_len                  //传入的身份证号长度


//取传入的身份证号、今天的日期、传入的身份证号长度
ls_identity_no	=	as_identity
ls_today			=	string(today(),'yyyy/mm/dd')
ll_identity_no_len	=	LEN(ls_identity_no)

//as_stru_idno.as_identity = ls_identity_no


//核查长度
if ls_identity_no = '' or isnull(ls_identity_no) or ll_identity_no_len <= 0  then
	     MessageBox("身份证号核查","身份证号码不能为空!",StopSign!,ok!)	
//		  as_err_msg = "身份证号码不能为空!"
	return False
elseif ll_identity_no_len <> 15 AND ll_identity_no_len <> 18 then
	MessageBox("身份证号核查","身份证号码位数不正确!",StopSign!,ok!)
//	as_err_msg = "身份证号码位数不正确!"
	return False
end if


//只能包含数字和字母X(15位只能包含数字,18位最后一位可以为X)
if not ( ( ll_identity_no_len = 18 and match(mid(ls_identity_no, 1, 17), "^[0-9]+$") and match(mid(ls_identity_no, 18, 1), "^[0-9X]+$") ) &
         or &
			( ll_identity_no_len = 15 and match(mid(ls_identity_no, 1, 15), "^[0-9]+$") ) &
		 ) &
	then
		choose case  ll_identity_no_len
			case 15
				MessageBox("身份证号核查","15位身份证号码只能包含数字!",StopSign!,ok!)
//				as_err_msg = "15位身份证号码只能包含数字!"
				return False
			case 18
				MessageBox("身份证号核查","18位身份证号码只能包含数字和X,X只能在最后一位!",StopSign!,ok!)
//				as_err_msg = "18位身份证号码只能包含数字和X,X只能在最后一位!"
				return False
		end choose				
end if


//取区域编码
//as_stru_idno.as_area_code = mid(ls_identity_no, 1, 6)


//提取年份
if ll_identity_no_len = 15 then //身份证长度为 15 的处理,  认为15位的年 = 19**
	ls_year = mid(ls_identity_no, 7, 2)
	ls_month = mid(ls_identity_no, 9, 2)
	ls_day = mid(ls_identity_no, 11, 2)
	ls_year = '19' + ls_year//year is only 20 century
	ls_date = ls_year +'/' + ls_month +'/' + ls_day
else
	ls_year = mid(ls_identity_no, 7, 4)

	if Left(ls_year,2) <> '19' and left(ls_year,2) <> '20' then
		MessageBox("身份证号核查","身份证号码中的出生年份不正确!",StopSign!,ok!)
//		as_err_msg = "身份证号码中的出生年份不正确!"
		return False
	end if

	ls_month = mid(ls_identity_no, 11, 2)
	ls_day = mid(ls_identity_no, 13, 2)
	ls_date = ls_year +'/' + ls_month +'/' + ls_day
end if

//核查月
if ls_month > '12' then
	MessageBox("身份证号核查","身份证号码中的出生月份不能大于12!",StopSign!,ok!)
//	as_err_msg = "身份证号码中的出生月份不能大于12!"
	return False
elseif ls_month <= '00' then
	MessageBox("身份证号核查","身份证号码中的出生月份不能小于01!",StopSign!,ok!)
//	as_err_msg = "身份证号码中的出生月份不能小于01!"
	return False
end if

//核查日
if ls_day <= '00' then
	MessageBox("身份证号核查","身份证号码的出生日小于01!",StopSign!,ok!)
//	as_err_msg = "身份证号码的出生日小于01!"
	return False
end if

CHOOSE CASE ls_month
	CASE '01','03','05','07','08','10','12'//大月的处理
		if ls_day > '31' then
			MessageBox("身份证号核查","身份证号码的出生日大于31!",StopSign!,ok!)
//			as_err_msg = "身份证号码的出生日大于31!"
			return False
	  end if
	CASE '04','06','05','09','11' //小月的处理
		if ls_day > '30' then
			MessageBox("身份证号核查","身份证号码的出生日大于30(本月无31日)!",StopSign!,ok!)
//			as_err_msg = "身份证号码的出生日大于30(本月无31日)!"
			return False
	  end if
	CASE '02'  //平年和闰年的处理
		ll_year = long(ls_year)
  
		if (mod(ll_year,4) = 0 and Mod(ll_year,100)<>0) or (Mod(ll_year,400) = 0) then   //闰年,二月份不能多于29天
			if ls_day > '29' then
				MessageBox("身份证号核查","闰年的二月份没有" + ls_day + "日!",StopSign!,ok!)
//				as_err_msg = "闰年的二月份没有" + ls_day + "日!"
				return False
			end if
		else//平年二月份不能大于28天
			if ls_day > '28' then
				MessageBox("身份证号核查","平年的二月份没有" + ls_day + "日!",StopSign!,ok!)
//				as_err_msg = "平年的二月份没有" + ls_day + "日!"
				return False
			end if
		end if
END CHOOSE

if ls_date > ls_today then
	MessageBox("身份证号核查","身份证号码的出生日期不正确!",StopSign!,ok!)
//	as_err_msg = "身份证号码的出生日期不正确!"
	return False
end if






/*==========================验证身份证的最后一位检验码==================================================+/
根据〖中华人民共和国国家标准GB11643-1999〗中有关公民身份号码的
规定,公民身份号码是特征组合码,由十七位数字本码和一位数字校验
码组成。排列顺序从左至右依次为:六位数字地址区位码,八位数字出
生日期码,三位数字顺序码和一位数字校验码。
地址区位码:表示居民常住户口所在县(市、区)的行政区划代码。
出生日期码:表示居民出生的年、月、日,其中年份用四位数字表示,
年、月、日之间不用分隔符。
数字顺序码:表示同一地址区位码所标识的区域范围内,对同年同月同
日出生的人员编定的顺序号。奇数分给男性,偶数分给女性。
数字校验码:根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校
验码计算出来的检验码。由(1,2,3,4,5,6,7,8,9,X)构成。
下面举例说明该计算方法并用代码实现。
公式:Ax=(∑(Ai×Wi))(mod 11)…………………………(1)
i----表示身份证号码字符从右至左包括校验码在内的位置序号;
Ai----表示第i位置上的数字号码;
Ax----数字校验码的值;
Wi----示第i位置上的加权因子;
公式:Wi=(2^(i-1))(mod 11)…………………………(2)
设某男性公民身份号码为51310119820113001,首先得到各个变量:
i18 17 16 15 14 13 12 11 10 9  8  7  6  5  4  3  2  1
Ai5  1  3  1  0  1  1  9  8  2  0  1  1  3  0  0  1  Ax
由公式(2)可得:
Wi7  9  10 5  8  4  2  1  6  3  7  9  10 5  8  4  2  1
Ai×Wi  35 9  30 5  0  4  2  9  48 6  0  9  10 15 0  0  2  A1
按照公式(1)计算:
∑(Ai×Wi)=(35+9+30+5+0+4+2+9+48+6+0+9+10+15+0+0+2)=184
184÷11=16+8/11
∑(Ai×Wi)(mod 11)=8
然后根据计算的结果,从下表中查出相应的校验码,X表示结果为10:
∑(Ai×WI)(mod 11)0 1 2 3 4 5 6 7 8 9 10
校验码字符值Ai1 0 X 9 8 7 6 5 4 3 2
根据上面的方法,查出计算结果为8的校验码为4所以该人员的公民身份
号码应该为513101198201130014。

/+===============================================================================================================*/

//核查校验码
if ll_identity_no_len = 18 then //18位的校验码的检验
  
	long	Ai=0
	string	code
	int	j
	
	for j	=	17 to 1 step -1
		Ai	=	Ai+(long(mid(ls_identity_no,j,1)))*(mod(2^((18)-j),11))
	next
	
	choose case mod(Ai,11)
		case 0
			code='1'
		case 1
			code='0'
		case 2
			code='X'
		case else
			code=string((12)-mod(Ai,11))
	end choose
	
	if right(as_identity,1) <> code then 
		  messagebox("身份证号核查","身份证号最后一位校验位不正确!",StopSign!,ok!)
//		as_err_msg = "身份证号最后一位校验位不正确!"
	  	return False
	end if 

end if


return True
  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vampire_if

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值