大陆身份证号码格式校验代码
来源:互联网 发布:淘宝手机详情页模板 编辑:程序博客网 时间:2024/05/05 13:13
- #ifndef __YSP_IDCARD_H__
- #define __YSP_IDCARD_H__
- #include <string>
- #include <stdlib.h>
- #include <ctype.h>
- #include <time.h>
- using namespace std;
- namespace NS_YSP
- {
- // wi=2(n-1)(mod 11)
- static int32_t wi[18]= { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1};
- // verify digit
- static char vi[11]= {'1','0','X','9','8','7','6','5','4','3','2'};
- class IDCard
- {
- public:
- //身份证号码校验
- static int32_t verify(string idcard, int32_t& gender/*0:女 1::表示男*/)
- {
- //把15位身份证升级为18位
- if( idcard.length()== 15)
- {
- idcard = uptoeighteen(idcard);
- }
- if(idcard.length()!= 18)
- {
- return -1;
- }
- //1-17必须是数字
- for(int32_t i= 0; i< 17;++i)
- {
- if( idcard[i]< '0'|| idcard[i]> '9')
- {
- return -2;
- }
- }
-
- //最后一位(第18位)为校验码,检查checksum值
- char verify = toupper(idcard[17]);
- if(verify != checksum(idcard))
- {
- return -3;
- }
-
- //第1-2位为省级行政区划代码,[11, 65] (第一位华北区1,东北区2,华东区3,中南区4,西南区5,西北区6)
- string strProvince= idcard.substr(0, 2);
- int32_t nProvince = atoi(strProvince.c_str());
- if( nProvince< 11 || nProvince> 65 )
- {
- return -4;
- }
- //第3-4为为地级行政区划代码,第5-6位为县级行政区划代码因为经常有调整,这块就不做校验
-
- //第7-10位为出生年份;//第11-12位为出生月份//第13-14为出生日期
- if(!checkdate(idcard.substr(6,8)))
- {
- return -5;
- }
- //第15-17位为顺序码,表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性
- string strSeq= idcard.substr(14,3);
- int32_t nSeq = atoi(strSeq.c_str());
- gender = nSeq%2;
- return 0;
- }
-
- static bool checkdate(conststring& strDate)
- {
- string strYear= strDate.substr(0, 4);
- int32_t nYear = atoi(strYear.c_str());
- time_t timep;
- time(&timep);
- struct tm *p= gmtime(&timep);
- if( p)
- {
- if( nYear< 1900 || nYear> 1900 + p->tm_year)
- {
- return false;
- }
- if( atoi(strDate.c_str())> ((1900 + p->tm_year)*10000+ p->tm_mon*100+ p->tm_mday) )
- {
- return false;
- }
- }
- string strMon= strDate.substr(4, 2);
- int32_t nMon = atoi(strMon.c_str());
- if( nMon<= 0 || nMon> 12 )
- {
- return false;
- }
-
- //月份天数表
- int32_t days[12]= {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
- bool bLeapYear =(nYear % 4== 0 && nYear% 100 != 0)|| (nYear% 400 == 0);
- if( bLeapYear)
- {
- days[1]= 29;
- }
- string strDay= strDate.substr(6, 2);
- int32_t nDay = atoi(strDay.c_str());
- if( nDay> days[nMon- 1 ]|| nDay <= 0)
- {
- return false;
- }
- return true;
- }
- //计算校验码
- static char checksum(string eightcardid)
- {
- int32_t remaining = 0;
- int32_t ai[18];
- if( eightcardid.length()== 18 )
- {
- eightcardid = eightcardid.substr(0, 17);
- }
- if( eightcardid.length()== 17 )
- {
- int32_t sum = 0;
- for(int32_t i = 0; i< 17; i++)
- {
- string k= eightcardid.substr(i, 1);
- ai[i]= atoi(k.c_str());
- }
- for(int32_t i = 0; i< 17; i++)
- {
- sum = sum+ wi[i]* ai[i];
- }
- remaining = sum% 11;
- }
-
- return vi[remaining];
- }
- //把15位身份证升级到18位身份证号码
- static string uptoeighteen(conststring& fifteencardid)
- {
- string eightcardid= fifteencardid.substr(0, 6);
- //加上年月日
- eightcardid = eightcardid+ "19";
- eightcardid = eightcardid+ fifteencardid.substr(6);
- //加上校验码
- eightcardid.push_back(checksum(eightcardid));
- return eightcardid;
- }
- };
- }
- #endif
转载 ::饶超勋 stevenrao.blog.chinaunix.net
0 0
- 大陆身份证号码格式校验代码
- 大陆身份证号码格式校验代码
- 大陆身份证号码格式校验代码
- 前端身份证号码校验js代码
- 身份证号码校验
- 身份证号码校验
- 身份证号码校验
- 身份证号码校验
- 身份证号码校验
- 身份证号码校验
- 校验身份证号码
- 身份证号码校验 java校验
- 很久没更新,贴点代码吧 身份证号码校验
- php身份证号码校验算法
- js 身份证号码校验实现
- PB身份证号码正确性校验
- JS校验身份证号码
- 身份证号码校验规则
- Android 微软雅黑、仿宋、黑体的使用
- openfire集群配置
- HashMap 哈希算法
- 关于换工作后的心得
- 【工作笔记】ElasticSearch从零开始学(三)—— 入门(聚合)
- 大陆身份证号码格式校验代码
- Ubuntu 下使用 ADB 调试 Android 应用时的设备识别问题
- 大理石在哪儿 where is the Marble? lower_bound()
- 单线程实现定时执行任务功能
- battery-historian工具环境部署及使用
- 数组赋值和传递(从网上看到的几种情况)
- 表单中的单选框、多选框中的name属性用途
- CAP理论以及hadoop组件
- C++运算符重载