A. 身份证的校验码怎么计算
http://zhangf.bokee.com/4013564.html
我国现行使用公民身份证号码有两种尊循两个国家标准,〖GB 11643-1989〗和〖GB 11643-1999〗。
〖GB 11643-1989〗中规定的是15位身份证号码:排列顺序从左至右依次为:六位数字地址码,六位数字出生日期码,三位数字顺序码,其中出生日期码不包含世纪数。
〖GB 11643-1999〗中规定的是18位身份证号码:公民身份号码是特征组合码,由十七位数字本体码和一位数字校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
地址码表示编码对象常住户口所在县(市、旗、区)的行政区划代码。
生日期码表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。
顺序码表示同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。
顺序码的奇数分给男性,偶数分给女性。
校验码是根据前面十七位数字码,按照ISO 7064:1983.MOD 11-2校验码计算出来的检验码。
为什么除11,在于计算校验码时的函数。请看下边的函数:
公式如下:
∑(a[i]*W[i]) mod 11 ( i = 2, 3, ..., 18 ) (1)
"*" 表示乘号
i--------表示身份证号码每一位的序号,从右至左,最左侧为18,最右侧为1。
a[i]-----表示身份证号码第 i 位上的号码
W[i]-----表示第 i 位上的权值 W[i] = 2^(i-1) mod 11
计算公式 (1) 令结果为 R
根据下表找出 R 对应的校验码即为要求身份证号码的校验码C。
R 0 1 2 3 4 5 6 7 8 9 10
C 1 0 X 9 8 7 6 5 4 3 2
由此看出 X 就是 10,罗马数字中的 10 就是X,所以在新标准的身份证号码中可能含有非数字的字母X。
~(重点看清楚)~ 这个函数展开就是:
a[1]*W[1]+a[2]*W[2]+……+a[18]*W[18]=?
?mod11=“?对11求模”
如:22mod11=2 23mod22也是2 33mod11=3
就是出于后面那个数,只取商不取余数
所以从函数和其展开式来看要对11求模,所一要除11
以下为列子:
*此函数功能:输入的15位或17位或18位的身份证号,返回校验后的最后一位
*
*-----------------------------
FUNCTION sfzjy
Parameters cID
DO CASE
CASE LEN(ALLTRIM(cID)) = 15
cID = STUFF(ALLTRIM(cID),7,0,"19")
CASE LEN(ALLTRIM(cID)) = 18 OR LEN(ALLTRIM(cID)) = 17
cID =LEFT(ALLTRIM(cID),17)
OTHERWISE
RETURN .F.
ENDCASE
If Len(ALLTRIM(cID))#17
Return .f.
Endif
nSum=Val(SubStr(cID,1,1)) * 7 ;
+ Val(SubStr(cID,2,1)) * 9 ;
+ Val(SubStr(cID,3,1)) * 10 ;
+ Val(SubStr(cID,4,1)) * 5 ;
+ Val(SubStr(cID,5,1)) * 8 ;
+ Val(SubStr(cID,6,1)) * 4 ;
+ Val(SubStr(cID,7,1)) * 2 ;
+ Val(SubStr(cID,8,1)) * 1 ;
+ Val(SubStr(cID,9,1)) * 6 ;
+ Val(SubStr(cID,10,1)) * 3 ;
+ Val(SubStr(cID,11,1)) * 7 ;
+ Val(SubStr(cID,12,1)) * 9 ;
+ Val(SubStr(cID,13,1)) * 10 ;
+ Val(SubStr(cID,14,1)) * 5 ;
+ Val(SubStr(cID,15,1)) * 8 ;
+ Val(SubStr(cID,16,1)) * 4 ;
+ Val(SubStr(cID,17,1)) * 2
*计算校验位
check_number=INT((12-nSum % 11)%11)
If check_number=10
check_number='X'
Endif
Return check_number
Endfunc
*-----------------------------
*
*此函数功能:输入的15位或18位身份证号,返回正确的18位的身份证号。
*
*---------------------------
FUNCTION IDCardTF
PARAMETERS cNumber
#DEFINE InvalidSize "身份证号码长度不正确!"
#DEFINE InvalidChar "身份证号码包括非法字符!"
#DEFINE InvalidDate "出生日期无效!"
#DEFINE InvalidReturnValue ".F."
PRIVATE cString
DO CASE
CASE LEN(cNumber) = 15
cString = STUFF(cNumber,7,0,"19")
CASE LEN(cNumber) = 18
cString =LEFT(ALLTRIM(cNumber),17)
OTHERWISE
MESSAGEBOX(InvalidSize,48,"信息提示")
RETURN InvalidReturnValue
ENDCASE
PRIVATE i,n,iRet
STORE 0 TO iRet
FOR i = 1 TO 17
n = SUBSTR(cString,i,1)
IF NOT ISDIGIT(n)
MESSAGEBOX(invalidChar,48,"信息提示")
RETURN invalidReturnValue
ENDIF
n = 2 ^ (18 - i) % 11 * VAL(n)
iRet = iRet + n
ENDFOR
iRet = iRet % 11 + 1
PRIVATE oldDateSet, oldCentury
PRIVATE oldStrictDate, BirthDay
oldDateSet = SET("DATE")
oldCentury = SET("CENTURY")
oldStrictDate = SET("STRICTDATE")
SET DATE ANSI
SET CENTURY ON
SET STRICTDATE TO 0
BirthDay = CTOD(SUBSTR(cString,7,4)+"-"+SUBSTR(cString,11,2)+"-"+SUBSTR(cString,13,2))
SET STRICTDATE TO &oldStrictDate
SET CENTURY &oldCentury
SET DATE &oldDateSet
IF EMPTY(BirthDay)
MESSAGEBOX(InvalidDate,48,"信息提示")
RETURN InvalidReturnValue
ENDIF
RETURN cString+SUBSTR("10x98765432",iRet,1)
ENDFUNC
*-----------------------------
*
*此函数功能:检验输入的15位或18位身份证号码是否为合法
*
*-----------------------------
FUNCTION sfzyn
LPARAMETERS lstr &&参数:lstr 传入的号码
LOCAL lstr,relyn,tsfz
LOCAL m1,m2,m3,m4,m,i,r,c,ai,wi
SET TALK OFF
SET DATE TO ANSI
SET CENT ON
relyn=.F. &&返回值
tsfz=ALLT(lstr)
*分别用m1,m2,m3,m4表示四个条件是否成立
STOR .T. TO m1,m2,m3,m4
*条件1:只能是15或18位
m1=IIF(LEN(tsfz)=15 OR LEN(tsfz)=18,.T.,.F.)
IF LEN(tsfz)=15 && 15位的号码
FOR i=1 TO 15 &&检查每一位是否为数字
m=ASC(SUBS(tsfz,i,1))
IF m<48 OR m>57 &&数字
m2=.F. &&若有一位不是就不再查
EXIT
ENDIF
ENDFOR
m="19" +SUBS(tsfz, 7,2) &&早期的号都是上个世纪的
m=m+"."+SUBS(tsfz, 9,2)
m=m+"."+SUBS(tsfz,11,2)
m=CTOD(m)
IF ISNULL(m) OR isblank(m)
m3=.F. &&生日不正确
ENDIF
ENDIF
IF LEN(tsfz)=18 && 18位的号码
FOR i=1 TO 17
m=ASC(SUBS(tsfz,i,1))
IF m<48 OR m>57
m2=.F.
EXIT
ENDIF
ENDFOR
m=SUBS(tsfz,7,4)
m=m+"."+SUBS(tsfz,11,2)
m=m+"."+SUBS(tsfz,13,2)
m=CTOD(m)
IF ISNULL(m) OR isblank(m)
m3=.F.
ENDIF
r=0 &&计算校验位
FOR i=18 TO 2 STEP -1
ai=VAL(SUBS(tsfz,19-i,1))
wi=MOD(2^(i-1),11)
r=r+ai*wi
NEXT
r=MOD(r,11)
DO CASE
CASE r=0
c="1"
CASE r=1
c="0"
CASE r=2
c="X"
OTHER
c=ALLTRIM(STR(12-r))
ENDCASE
IF UPPE(SUBS(tsfz,18,1))<>c
m4=.F. &&校验位与原码最末位不同
ENDIF
ENDIF
*四个条件全成立,则返回.t.
relyn=IIF(m1 AND m2 AND m3 AND m4,.T.,.F.)
RETU relyn
ENDFUN
*-----------------------------
*
*此函数功能:输入15位或18位的身份证号,返回被校验后的18位的身份证号,若身份证号非法,则返回空
*
*-----------------------------
FUNC sfjy
PARA msfz
ON ERRO RETU ''
DIME T(17)
PRIV msfz,T,sn,i
msfz=ALLT(msfz)
DO CASE
CASE LEN(msfz)=15
msfz=LEFT(msfz,6)+'19'+SUBS(msfz,7)
CASE LEN(msfz)=18
msfz=LEFT(msfz,17)
OTHE
RETU ''
ENDC
FOR i=1 TO 17
IF !ISDI(SUBS(msfz,i,1))
RETU ''
ENDI
ENDF
IF !LEFT(msfz,2)$'11,12,13,14,15,21,22,23,31,32,33,34,35,36,37,41,42,43,44,45,46,50,51,52,53,54,61,62,63,64,65,71,81,82'
RETU ''
ENDI
IF EMPT(DATE(VAL(SUBS(msfz,7,4)),VAL(SUBS(msfz,11,2)),VAL(SUBS(msfz,13,2))))
RETU ''
ENDI
sn=0
T(1)=7
T(2)=9
T(3)=10
T(4)=5
T(5)=8
T(6)=4
T(7)=2
T(8)=1
T(9)=6
T(10)=3
T(11)=7
T(12)=9
T(13)=10
T(14)=5
T(15)=8
T(16)=4
T(17)=2
FOR i=1 TO 17
sn=sn+VAL(SUBS(msfz,i,1))*T(i)
ENDF
sn=MOD(sn,11)
ON ERRO
RETU msfz+SUBS('10X98765432',sn+1,1)
B. 身份证号码尾号的校验码是由什么公式计算出来的
校验码是根据前面十七位数字码,按照ISO
7064:1983.MOD
11-2校验码计算出来的检验码。
具体的公式举例说明为:
某男性公民身份号码本体码为34052419800101001,首先按照公式计算:∑(ai×Wi)(mod
11),其中,i表示号码字符从右至左包括校验码在内的位置序号;
a[i]表示第i位置上的号码字符值;
W[i]示第i位置上的加权因子,其数值依据公式
W[i]
=
2^(i-1)
mod
(11)计算得出。
则,设R=∑(a[i]×W[i])(mod
11)
=
2,同时R的值【0
1
2
3
4
5
6
7
8
9
10】对应取值为【1
0
X
9
8
7
6
5
4
3
2】。
计算结果为2的校验码为X,所以该人员的公民身份号码应该为
34052419800101001X。
(2)身份证校验码计算方法c语言程序扩展阅读:
身份证号码的结构和形式:
1、号码的结构:公民身份号码是特征组合码,由十七位数字本体码和一位校验码组成。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
2、地址码:表示编码对象常住户口所在县(县级市、旗、区)的行政区划代码,按GB/T2260的规定执行。
3、出生日期码:表示编码对象出生的年、月、日,按GB/T7408的规定执行,年、月、日代码之间不用分隔符。
4、顺序码:表示在同一地址码所标识的区域范围内,对同年、同月、同日出生的人编定的顺序号,顺序码的奇数分配给男性,偶数分配给女性。
5、校验码:根据前面十七位数字码,按照ISO
7064:1983.MOD
11-2校验码计算出来的检验码。
参考资料来源:网络-身份证号码
参考资料来源:网络-身份证校验位
C. C语言设计程序判断身份证号的合法性,并输出到指定日期的天数
天数包括2019.4.2这天吗?
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#defineTHISYEAR2019
#defineTHISMONTH4
#defineTODAY2
#defineDATA20190402
#defineMOD11
constintdays[2][12]={
{31,28,31,30,31,30,31,31,30,31,30,31},
{31,29,31,30,31,30,31,31,30,31,30,31}
};
constintWF[17]={
7,9,10,5,8,4,2,1,6,
3,7,9,10,5,8,4,2
};
constcharPIN[11]={
'1','0','X','9','8','7',
'6','5','4','3','2'
};
intleapyear(int);//判断闰年
ints2d(char*,int,int);
intcountdays(int,int,int);
intmain(void){
intis_valid=1;//ID是否合格的标志
inty,m,d;
charID[19];
scanf("%s",ID);
if(strlen(ID)!=18){
is_valid=0;
}
else{
for(inti=0;i<17;i++){
if(!isdigit(ID[i])){
is_valid=0;
break;
}
}
y=s2d(ID,6,9);
m=s2d(ID,10,11);
d=s2d(ID,12,13);
if(m<1||m>12||d>31||d<1||
(leapyear(y)&&m==2&&d>29)||
10000*y+100*m+d>=DATA)
is_valid=0;
intsum=0;
for(inti=0;i<17;i++){
sum+=(ID[i]-'0')*WF[i];
}
if(toupper(PIN[sum%MOD])!=toupper(ID[17]))
is_valid=0;
}
if(is_valid){
inttotaldays=countdays(y,m,d);
printf("%d ",totaldays);
}
else
puts("No");
return0;
}
intleapyear(inty){
return(y%4==0&&y%100!=0)||(y%400==0);
}
ints2d(char*id,ints,inte){
intresult=0;
for(inti=s;i<=e;i++)
result=10*result+(id[i]-'0');
returnresult;
}
intcountdays(inty,intm,intd){
inttotal=0;
if(y<THISYEAR){
for(inti=11;i>=m;i--){
total+=days[leapyear(y)][i];
}
total+=days[leapyear(y)][m-1]-d+1;
for(inti=y+1;i<THISYEAR;i++)
total+=leapyear(i)?366:365;
for(inti=0;i<THISMONTH-1;i++)
total+=days[leapyear(THISYEAR)][i];
total+=TODAY;
}
else{
for(inti=y-1;i<THISMONTH-1;i++)
total+=days[leapyear(THISYEAR)][i];
total+=TODAY;
}
returntotal;
}
D. C++编写一个计算身份证校验位的函数,函数原型为char check(char s[17])
//开始没注意,既然命题要求函数原型必须是charcheck(chars[17])
#include<iostream>
usingnamespacestd;
charcheck(chars[17])
{
intm,y;
charp='2';//<--p要改成char型,并且要返回的,这是根据你写的后续代码来判断的
//下面的输入代码放到main函数中,交把用户输入结果以参数形式传入check()
//cout<<"输入身份证号前17位:"<<endl;
//cin>>s>>endl;
m=s[0]*7+s[1]*9+s[2]*10+s[3]*5+s[4]*8+s[5]*4+s[6]*2+s[7]*1+s[8]*6+s[9]*3+s[10]*7+s[11]*9+s[12]*10+s[13]*5+s[14]*5+s[15]*4+s[16]*2;//<--这里s[14]4]*5是输错了吧,改为s[14]*5
switch(y=m%11)
{
//intX,p;//<--这行代码是多余的。下面的p值全部改成字符型数据,用单引号括起来
case0:
p='1';break;
case1:
p='0';break;
case2:
p='X';break;
case3:
p='9';break;
case4:
p='8';break;
case5:
p='7';break;
case6:
p='6';break;
case7:
p='5';break;
case8:
p='4';break;
case9:
p='3';break;
default:
p='2';
}
returnp;//<--这行是必须添加的,因为你是在函数外面检验第18位字符
}
intmain()
{
charm,p;//<--这行代码是必须添加的,因为你下面使用了它们
chars[17];//<--用来保存用户输入的17位身份证号码
cout<<"输入身份证号前17位:"<<endl;//<--check()里的输入代码移到这
cin>>s;//<--去掉>>endl;否则编译会报错。
p=check(s);//<--charcheck(chars[17])函数调用要改成这样
cout<<"输入第18位m"<<endl;
cin>>m;////<--同样,要去掉>>endl
if(p==m)
{
cout<<"合法身份证号码"<<endl;
}
else//<--这里没有判断就不要if了
{
cout<<"身份证号码不正确"<<endl;
}
return0;//<--加一个return
}
// 也没有帮你做什么优化处理了,完全是根据你自己的思路来改错。修改后,应该能正常编译,在输入正确范围内的数值应该是能正确处理的。其实,你这里还要考虑内存溢出的问题,如果第一次,你输入的身份证号码不止前17位,而是多输入字符的话,就会导致内存溢出了。
E. 身份证号码的最后一位校验码是怎么计算出来的
先将身份证前面的17位数分别乘以不同的系数,然后将每一个相乘的结果相加,用所得之和除以11,看余数是多少,余数是0--9尾数就是0-9,如果余数是10,那么身份证的第18位数字就用罗马数字的【χ代替】。
因为是10的话就有19位数字了,与身份证号码十八位数的国家标准不相符合。因为是10的话就有19位数字了,与身份证号码十八位数的国家标准不相符合。
X:英语中第24个字母。X 表示未知、无限,X 还有“目标”和“希望”,X 在社会学界表示“完美”,千言万语都可以用 X 来传递。数学中 X 在方程中通常表示未知数的值。在罗马数字中,X 表示十。
(5)身份证校验码计算方法c语言程序扩展阅读:
身份证号码18位数字其表示的含义分别为:
第1、2位, 所在省份的代码;
第3、4位 :所在城市的代码;
第5、6位:所在区县的代码;
第7——14位 :出生年、月、日
(7、8、9、10位是年,11、12位是月,13、14位是日);
第15、16位 :所在地派出所的代码;
第17位 :奇数1、3、5、7、9表示男性,偶数2、4、6、8表示女性;
第18位:校检码:为0——9数字,或者罗马数字χ表示。
F. 用c语言编程求 18位 身份证的验证码
除了楼上所说的,在补充一点
1:char id[19]; //最后一个字节是用于'\0'的
2:除了这个原因,还有一个更重要的是gets得到的都是字符,在你的jisuan函数里,for循环中
result+=((*p)*(*q));
这句话其实是字符的ascII码相乘的,并不是数字相乘,可以改成
(((*p) - '0') * ((*q) - '0'));
这样就是对应字符的数字相乘了(这个很好理解吧?)
3:虽然jisuan返回的是个比较小的数,但是在for循环里计算的时候result定义成char型的会有溢出,会对你的结果有影响吧,我建议改成unsigned int
G. C语言作业:4. 设计身份证号合法性验证程序
#include
"stdio.h"
void
main()
{
int
i;
/*身份证的第i位*/
int
s[17];
/*定义一个数组用来存放身份证的前17位*/
int
t[17];
/*各位相乘后的数组*/
int
m;
/*余数*/
int
t18;
/*身份证的第18位0--9*/
char
t18c;
/*身份证的第18位X*/
long
int
sum=0;
for(i=0;i<17;i++)
{
printf("请输入身份证的第%d位:",i+1);
scanf("%d",&s[i]);
switch(i+1)
{
/*身份证的1到17位要乘的数一次是7
9
10
5
8
4
2
1
6
3
7
9
10
5
8
4
2
*/
case
1:t[i]=s[i]*7;break;
case
2:t[i]=s[i]*9;break;
case
3:t[i]=s[i]*10;break;
case
4:t[i]=s[i]*5;break;
case
5:t[i]=s[i]*8;break;
case
6:t[i]=s[i]*4;break;
case
7:t[i]=s[i]*2;break;
case
8:t[i]=s[i]*1;break;
case
9:t[i]=s[i]*6;break;
case
10:t[i]=s[i]*3;break;
case
11:t[i]=s[i]*7;break;
case
12:t[i]=s[i]*9;break;
case
13:t[i]=s[i]*10;break;
case
14:t[i]=s[i]*5;break;
case
15:t[i]=s[i]*8;break;
case
16:t[i]=s[i]*4;break;
case
17:t[i]=s[i]*2;break;
}
sum=sum+t[i];
}
printf("前17位相乘后的和为%ld\n",sum);
m=sum%17;
printf("对17取余后的值位:",m);
switch(m)
{
/*各个余数所对应第18位身份证号1
0
X
9
8
7
6
5
4
3
2*/
case
0:t18=1
;printf("这是一个合法的身份证号码,第18位是%d",t18);break;
case
1:t18=0
;printf("这是一个合法的身份证号码,第18位是%d",t18);break;
case
2:t18c='X';printf("这是一个合法的身份证号码,第18位是%c",t18c);break;
case
3:t18=9
;printf("这是一个合法的身份证号码,第18位是%d",t18);break;
case
4:t18=8
;printf("这是一个合法的身份证号码,第18位是%d",t18);break;
case
5:t18=7
;printf("这是一个合法的身份证号码,第18位是%d",t18);break;
case
6:t18=6
;printf("这是一个合法的身份证号码,第18位是%d",t18);break;
case
7:t18=5
;printf("这是一个合法的身份证号码,第18位是%d",t18);break;
case
8:t18=4
;printf("这是一个合法的身份证号码,第18位是%d",t18);break;
case
9:t18=3
;printf("这是一个合法的身份证号码,第18位是%d",t18);break;
case
10:t18=2
;printf("这是一个合法的身份证号码,第18位是%d",t18);break;
default:printf("这不是一个合法的身份证号码");
}
printf("\n");
}
H. c语言编程题求帮忙!!
#include<stdio.h>
intmain(void)
{
intxishu[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
chars[20]="10X98765432";
charid[20];
intsum=0,i,yushu;
printf("请输入身份证号:");
gets(id);
for(i=0;i<17;i++)
{
sum=sum+(xishu[i]*(id[i]-'0'));
}
yushu=sum%11;
printf("%c ",s[yushu]);
return0;
}
I. 身份证校验码计算公式是什么
校验码是根据前面十七位数字码。
具体的公式举例说明为:
某男性公民身份号码本体码为34052419800101001,首先按照公式计算:∑(ai×Wi)(mod11),其中,i表示号码字符从右至左包括校验码在内的位置序号;
这4个的前2个代表着我们身份证的派出所的代码,那么接着的是1个数字是根据性别来定的,奇数代表的是男性的身份证,偶数代表的是女性的身份证,最后一个数字就是我们今天的重点,有的是数字,有的人是“X”。
(9)身份证校验码计算方法c语言程序扩展阅读:
对于我们的身份证,其实还有个讲究的,就是我们身份证倒数的后两位数字,其实用来区分男女性别的,倘若你细心可以发现这个数字是奇数的,那个身份证的人就是男性,反之便是女的。
此外,我们生日数字后面那4位,最后两个已经解释了是怎么一回事了,另外的那两个数字便是我们所出生那时的顺序,是以出生的地方为标准的呢,所以其实我们的身份证可是很有讲究的。
J. C语言中,如何生成身份证年份的随机数(用rank()函数),并校验身份证是否合法
最后4位数字中的前两位表示当地派出所的编码;
倒数第二位表示公民是男性还是女性(男性用单数,女性用双数);
最后一位数字是一个随机数,又称为校验码。 用来检验身份证的正确性。校检码可以是0~9的数字,有时也用x表示。