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表示。