我国的居民身份证号码是特征组合码,由十七位数字本体码和一位校验码组成。
排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。
第一、二位表示省级行政区。
第一位数字是以前的大区制代码。第二位是大区所在省市编码。
具体省(直辖市,自治区,特别行政区)编码如下
记不住省份简称的可以跳过去看看
https://blog.csdn.net/qq_55342245/article/details/113815397
第三、四位表示地级行政区。01一般表示本省省会
就像车牌,A表示本省省会,B一般是本省的二线城市
辽A是沈阳 辽B是大连,黑A是哈尔滨 黑B是齐齐哈尔,川A是成都 川B是绵阳,云A是昆明 云南没有B的牌照
第五、六位表示县级行政区。01一般表示本市市辖区
210101辽宁省沈阳市市辖区 210201辽宁省大连市市辖区
230101黑龙江省哈尔滨市市辖区 230201黑龙江省齐齐哈尔市市辖区
510101四川省成都市市辖区 510701四川省绵阳市市辖区
(身份证号码第七位到第十四位)表示编码对象出生的年、月、日,其中年份用四位数字表示,年、月、日之间不用分隔符。例如:1981年05月11日就用19810511表示。
(身份证号码第十五位到十七位)表示在同一地址码所标识的区域范围内,对同年、月、日出生的人员编定的顺序号。其中第十七位奇数分给男性,偶数分给女性。(我国古代,奇数为阳,偶数为阴)
根据前面十七位数字码,按按一定规则计算出来。
公式:最后一位 = ( 12 − ∑ i = 2 18 a i w i m o d 11 ) m o d 11 = ( 12- \sum_{i=2}^{18}a_{i}w_{i} mod 11) mod11 =(12−∑i=218aiwimod11)mod11
mod 是取余数的意思。 例(36 mod 5)=1, (46 mod 8)=6
ai 是从右往左数第i位,加权因子wi = 2(i-1) mod 11
身份证是18位,所以a2是倒数第二位,正数第17位
因为最后一位是除以11取余数得到,就有0~10这十一种情况,那么就得用X(X是罗马数字的10)来代替10,因为如果用10做尾号,那么此人的身份证就变成了19位,而19位的号码违反了国家标准。
十八位身份证还可以用这个公式验证: ∑ i = 1 18 a i w i ≡ 1 ( m o d 11 ) \sum_{i=1}^{18}a_{i}w_{i} \equiv 1 ( mod 11) ∑i=118aiwi≡1(mod11)
“ ≡ \equiv ≡ ”是同余符号。
例:
16 ≡ \equiv ≡ 11 ( mod 5) 16除以5=3…1 11除以5=2…1 余数都是1
25 ≡ \equiv ≡ 3 ( mod 11) 25除以11=2…3 3除以11=0…3 余数都是3
这个公式的另一种写法是: ( ∑ i = 1 18 a i w i ) m o d 11 = 1 ( \sum_{i=1}^{18}a_{i}w_{i}) mod 11 = 1 (∑i=118aiwi)mod11=1
安利几个千年难遇的身份证号(如有冒犯请联系我删除)
这些身份证是有意义的。但形成这样的身份证号,必须要让公安机关分配给你的顺序码是由0和2组成,而且0和2的还得有一个正确的搭配顺序
有兴趣的还可以自己多找几个
220202200002022002 吉林省吉林市昌邑区2000年2月2日出生的女孩
220202200002200200 吉林省吉林市昌邑区2000年2月20日出生的女孩
220202202002020022 吉林省吉林市昌邑区2020年2月2日出生的女孩
220202202002022220 吉林省吉林市昌邑区2020年2月2日出生的女孩
220202202002202002 吉林省吉林市昌邑区2020年2月20日出生的女孩
//获取身份证号里的信息
public static void getInfo(String s){
String area=s.substring(0,6);
String year=s.substring(6,10);
String month=s.substring(10,12);
String day=s.substring(12,14);
String num=s.substring(14,17);
String checkCode=s.substring(17);
System.out.println("地区码:"+area);
System.out.println("出生日期:"+year+"年"+month+"月"+day+"日");
System.out.println("顺序码:"+num);
System.out.println("校验码:"+checkCode);
if (Integer.parseInt(s.substring(16,17))%2==0){
System.out.println("性别:女");
}else{
System.out.println("性别:男");
}
}
public static String getArea(String id){
Map<String,String> map=new HashMap<String,String>(){{
put("11","北京市");put("12","天津市");put("13","河北省");put("14","山西省");put("15","内蒙古自治区");
put("21","辽宁省");put("22","吉林省");put("23","黑龙江省");
put("31","上海市");put("32","江苏省");put("33","浙江省");put("34","安徽省");put("35","福建省");put("36","江西省");put("37","山东省");
put("41","河南省");put("42","湖北省");put("43","湖南省");put("44","广东省");put("45","广西壮族自治区");put("46","海南省");
put("50","重庆市");put("51","四川省");put("52","贵州省");put("53","云南省");put("54","西藏自治区");
put("61","陕西省");put("62","甘肃省");put("63","青海省");put("64","宁夏回族自治区");put("65","新疆维吾尔自治区");
put("71","台湾省");
put("81","香港特别行政区");put("82","澳门特别行政区");
}};
String area=id.substring(0,2);
if (map.containsKey(area)){
return map.get(area);
}else{
return "地区码无效";
}
}
简单的
//(简单)
public static void doVerify(String id) {
char pszSrc[] = id.toCharArray();
int sum = 0;
//身份证的前十七位分别乘以相应的加权因子
int wi[] = {7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2};
//根据余数去匹配对应的数字
char rem[] ={'1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'};
for (int i = 0; i < 17; i++) {
sum += (int)(pszSrc[i]-'0') * wi[i];
}
int j = sum % 11;
System.out.println("校验位是:"+rem[j]);
}
专业的
公式:最后一位 = ( 12 − ∑ i = 2 18 a i w i m o d 11 ) m o d 11 = ( 12- \sum_{i=2}^{18}a_{i}w_{i} mod 11) mod11 =(12−∑i=218aiwimod11)mod11
public static void Judge(String str){
int sum = 0;
for(int i=0;i<17;i++){
char c = str.charAt(i);
int n =c-'0';//数字字符转对应的数字
int wi=1;
//加权因子wi = 2^(i-1) mod 11 从右往左数
//也就是 w1=(2^17)%11 w2=(2^16)%11 w17=(2^1)%11
wi=wi<<(17-i)//左移,这里相当于乘以2的(17-i)次方
wi=wi%11;//加权因子计算完成
sum+=n*wi;
}
int x=(12-sum%11)%11;
System.out.println("校验位是:"+x);
}
import java.util.Calendar;
import java.util.Scanner;
public class Shen {
public static void main(String[] args){
Scanner input=new Scanner(System.in);
System.out.println("请输入的你身份证号:");
String s= input.next();
if (s.length()==18 && isNumString(s)){
String a=s.substring(0,6);
String y=s.substring(6,10);;
String m=s.substring(10,12);;
String d=s.substring(12,14);;
String n=s.substring(14,17);;
String checkCode=s.substring(17);;
Integer area = new Integer(a);
Integer year = new Integer(y);
Integer month = new Integer(m);
Integer day = new Integer(d);
Integer num = new Integer(n);
if (isNumString(s) && Judge(s)){
if(Year(year)){
if (Month(month)){
if (Day(year,month,day)){
System.out.println("身份证号有效");
System.out.println("地区码:"+area);
System.out.println("出生日期:"+year+"年"+month+"月"+day+"日");
System.out.println("顺序码:"+num);
System.out.println("校验码:"+checkCode);
if (Integer.parseInt(s.substring(16,17))%2==0){
System.out.println("性别:女");
}else{
System.out.println("性别:男");
}
}else{
System.out.println("身份证号上的日期有误");
}
}else{
System.out.println("身份证号上的月份有误");
}
}else{
System.out.println("身份证号上的年份有误");
}
}else{
System.out.println("身份证号无效");
}
}else{
System.out.println("身份证号码必须是由数字组成的十八位");
}
}
//判断身份证号是否合法
public static boolean Judge(String str){
int sum = 0;
int[] arr=new int[18];
char ch = str.charAt(17);
if (ch=='X' || ch=='x'){
arr[17]=10;
}else{
arr[17]=ch-'0';
}
for(int i=0;i<17;i++){
char c = str.charAt(i);
arr[i]=c-'0';//数字字符转对应的数字
}
for(int i=0;i<18;i++){
//ai 表示的是从右往左身份证的第i位数字
int wi=1;
//加权因子wi = 2^(i-1) mod 11
for (int j = 0; j < i; j++) {//计算加权因子
wi=wi*2;
}
wi=wi%11;
sum+=arr[17-i]*wi;
}
if (sum%11==1){
return true;
}else{
return false;
}
/*或者是
//身份证最后一个数字=(12-前十七位的sum然后模11)模11,
if (arr[17]==(12-(sum-arr[17])%11)%11){
return true;
}else{
return false;
}*/
}
//判断时间是否合法
public static boolean Year(Integer year){
Calendar now = Calendar.getInstance();
if (year>=1900 && year<=now.get(Calendar.YEAR)) {
return true;
}else{
return false;
}
}
public static boolean Month(Integer month){
if (month>=1 && month<=12) {
return true;
}else{
return false;
}
}
public static boolean Day(Integer year,Integer month,Integer day){
if (month>=1 && month<=12) {
switch (month){
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
if (day>=1 && day <=31) {
return true;
}else{
return false;
}
case 4:
case 6:
case 9:
case 11:
if (day>=1 && day <=30) {
return true;
}else{
return false;
}
case 2:
if (year%4==0&&year%100!=0||year%400==0) {
if (day>=1 && day<=29){
return true;
}else{
return false;
}
}else{
if (day>=1 && day<=28){
return true;
}else{
return false;
}
}
default:
return false;
}
}else{
return false;
}
}
//判断前17位是不是数字
private static boolean isNumString(String str) {
if (str.length() == 0 || str == null)
return false;
for (int i = 0; i < 17; i++) {
char ch = str.charAt(i);
if (!(ch >= '0' && ch <= '9')) {
return false;
}
}
return true;
}
}