使用java语言来推测火车票上完整身份证信息

周末在浏览公众号时看到一个有趣的文章,借鉴了对方的思路,使用java语言来完成推测火车票上完整身份证信息的功能。(可以根据身份证号的前6位上网查询我国地区的地址码,得到对方的(市、镇、区),应该有相关接口,有兴趣的朋友可以试试),内容如下:

// An highlighted block
package com;

import java.util.Arrays;
import java.util.Scanner;
/**
 * 使用火车票隐藏的日期下的号码来计算可能的身份证号码
 * @author Administrator
 *
 */
public class ID {
	static int m=0;
	public static void main(String[] args) {
		Scanner scanner=new Scanner(System.in);
		System.out.println("请输入身份证号,隐藏为以 * 代替,以回车结束输入:");
		String id =scanner.nextLine();
		s(id);
	}
	
	
	/**
	 * 计算主体,生成符合实际的日期
	 * @param id 输入身份证号
	 */
	public static void s(String id) {
		StringBuffer s = new StringBuffer();
		int a[][] = new int[3][18];
		
		//输入身份证号的序号
		for (int i = a[0].length; i > 0; i--) {
			a[0][a[0].length - i] = i;
		}
		System.out.println("序号信息:"+Arrays.toString(a[0]));//输出序号
		
		//计算身份证号的每一位的权重
		for (int i = 0; i < a[0].length; i++) {
			a[1][i] = (int) (Math.pow(2, a[0][i] - 1) % 11);
		}
		System.out.println("权重信息:"+Arrays.toString(a[1]));//输出权重信息
		
		//将输入的身份证号转为字节数组
		char[] ID = id.toCharArray();
		
		//将身份证号的前17位以int型存入数组中
		for (int i = 0; i < a[0].length-1; i++) {
			if(i>9&&i<14) continue;
			a[2][i] = Integer.parseInt(String.valueOf(ID[i]));
		}
		
		//判断当前身份证号的最后一位是不是x,(非int型)
		if(ID[17]=='x'){
			a[2][17] =10;
		}else{
			a[2][17] =Integer.parseInt(String.valueOf(ID[17]));
		}
		
		//提取年份,计算平年闰年
		String q = "";
		for (int i = 6; i < 10; i++) {
			q += a[2][i];
		}
		int year = Integer.parseInt(q);
		
		//计算符合实际条件的月份
		for (int i = 1; i <= 12; i++) {
			if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10 || i == 12) {
				for (int j = 1; j <= 31; j++) {
					if (i < 10) {
						s.append(0).append(i);
					} else {
						s.append(i);
					}
					if (j < 10) {
						s.append(0).append(j);
					} else {
						s.append(j);
					}

					f(s.toString(), a);//计算是否符合身份证指定规则
					s.delete(0, 4);//清空s
				}
			} else if (i == 2) {
				int n = 0;
				if ((year % 400 == 0) || (year % 4 == 0 && year % 100 != 0)) {
					n = 29;
				} else {
					n = 28;
				}

				for (int j = 1; j <= n; j++) {
					s.append(0).append(2);
					if (j < 10) {
						s.append(0).append(j);
					} else {
						s.append(j);
					}

					f(s.toString(), a);
					s.delete(0, 4);
				}

			} else {
				for (int j = 1; j <= 30; j++) {
					if (i < 10) {
						s.append(0).append(i);
					} else {
						s.append(i);
					}
					if (j < 10) {
						s.append(0).append(j);
					} else {
						s.append(j);
					}

					f(s.toString(), a);
					s.delete(0, 4);
				}
			}
		}
	}

	/**
	 * 判断身份证号是否符合制定规则,输出符合条件的身份证号
	 * @param da 日期
	 * @param a 数组
	 */
	public static void f(String da, int[][] a) {

		//将日期填入数组中
		char[] DA = da.toCharArray();
		for (int i = 0; i < DA.length; i++) {
			a[2][i + 10] = Integer.parseInt(String.valueOf(DA[i]));

		}

		int Sum = 0;
		for (int i = 0; i < a[0].length - 1; i++) {//计算身份证号校验位的方法
			Sum = Sum + a[1][i] * a[2][i];
		}
		int r = Sum % 11;
		
		if ((((12 - r) % 11) == a[2][17])) {//规则
			m++;
			System.out.println("第"+(m<10?"0"+m:m)+"个符合条件的身份证号为:" +Arrays.toString(a[2]));
			
			/*
			 * 由于上述判断的结果并不唯一,所有可以在延伸一下:用得到的身份证号去调用12306的API接口,判断回调结果,
			 * 12306API接口的调用需要申请Key,感兴趣的可以自行尝试
			 * */
			
		}

	}
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值