A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 L10052108 于 2016-11-10 16:03 编辑

     身份证号码可以告诉我们什么?

    身份证号码,总共有18位,这18位代表着,你的籍贯,生日,性别
  
行号
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
举例
5
3
0
1
0
2
1
9
2
0
0
5
0
8
0
1
1
X
含义
升级行政区代码
地级行政区代码
县级行政区代码
出生年
出生月
出生年日
顺序码奇数是男性,偶数是女性
校验







   我曾经想过,拿到一个身份证号码,如何知道他相关的信息呢。
以前就有想法,写一段程序,进行实现,可惜当时对编程时一知半解的。没有做出来,经过最近这段时间学习
~~~~~~~今天花了几个小时做出来了~~~~~~~~~~
趁着高兴的尽头,把它发表出来

有了你的生日,我还不把你的年龄,来到世上的天数算出来。呵呵呵,我有点邪恶了
  • 获取出生年月日:控制台输出
太简单了,字符串的解析呗!
性别也很简单,只要看15-17是奇数还是偶数
[AppleScript] 纯文本查看 复制代码
// 获取生日信息
                String str = id.substring(6, 10).concat(" 年  ")
                                .concat(id.substring(10, 12)).concat(" 月  ")
                                .concat(id.substring(12, 14)).concat(" 日  ");
                System.out.println("你的出生日期是:" + str);
性别也很简单,只要看15-17是奇数还是偶数
我写成了方法,只要输入身份证号码,就可以,调用了
[AppleScript] 纯文本查看 复制代码
private static String getSex(String id) {
                // TODO Auto-generated method stub
                // 15-17顺序码,同一个地区同年同月同日生的编码 奇数是男性,偶数是女性

                int num = Integer.parseInt(id.substring(14, 17));
                String sex;
                if (num % 2 == 1) {
                        // System.out.println("性别:男");
                        sex = "男";
                } else {
                        // System.out.println("性别:女");
                        sex = "女";
                }

                return sex;
        }
下面是你的籍贯

我采用,把网上查到相关的记录,写到一个文件内properties 后缀的文件内,(其实properties是一个集合,同时也是IO流读取文件)我觉的使用这种方式,很简单,好用
[AppleScript] 纯文本查看 复制代码
        private static String getAddress(String id) {
                // TODO Auto-generated method stub
                // 创建文件对象
                Properties p = new Properties();
                try {
                        p.load(new FileInputStream("sfzid.properties"));

                        // 加载文件
                        String str1 = id.substring(0, 6);
                        String address = p.getProperty(str1);
                        // System.out.println(address);

                        return address;
                } catch (FileNotFoundException e) {
                        // TODO Auto-generated catch block
                        // e.printStackTrace();
                        System.out.println("找不到文件");
                } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                }
                //

                return null;

        }
这还不算复杂:身份证校验规则,很可恶,每一位进行校验,算出第18
以前我做单片机,编写通讯协议时候,做的最多就是校验了,什么奇偶数、crc校验。
只要有规则,就好办!看程序


正则表达式了,太爱它了,有了正则表达式,很多时候,代码简化。可读增强了很多。那种感觉爽!感觉有种编程艺术;
[AppleScript] 纯文本查看 复制代码
/*
         * 身份证校验码的计算方法
         * 
         * 1、将前面的身份证号码17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4
         * -2。
         * 
         * 2、将这17位数字和系数相乘的结果相加。
         * 
         * 3、用加出来和除以11,看余数是多少?
         * 
         * 4、余数只可能有0-1-2-3-4-5-6-7-8-9-10这11个数字。其分别对应的最后一位身份证的号码为1-0-X
         * -9-8-7-6-5-4-3-2。
         * 
         * 5、通过上面得知如果余数是3,就会在身份证的第18位数字上出现的是9。如果对应的数字是10,身份证的最后一位号码就是罗马数字x
         */

        private static boolean checkID(String id) {
                // TODO Auto-generated method stub

                // 使用正则表达式判断 组成规则 前17位是数字,后1为是 数字或x
                boolean flag = false;
                String regex = "\\d{17}[0-9Xx]";
                // flag = id.matches(regex);
                if (!id.matches(regex)) {
                        return false;
                }

                // 7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。
                int[] d1 = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
                // 1-0-X -9-8-7-6-5-4-3-2。
                String[] endId = { "1", "0", "X", "9", "8", "7", "6", "5", "4", "3",
                                "2" };

                int sum = 0;
                char[] chs = id.toCharArray();
                for (int x = 0; x < 17; x++) {
                        sum = sum + Integer.parseInt(String.valueOf(chs[x])) * d1[x];
                }

                // 获取最后一位的字符
                String end = endId[sum % 11];

                flag = end.equalsIgnoreCase(id.substring(17));

                return flag;

        }
下面给出properties文件源码部分源码:前边六位数字是编号,后面的汉字,被自动转成其他编码了,不需要我们看懂,程序可以读懂就好。资料来源是我从网上下载的excel文件。在附录里有。
[AppleScript] 纯文本查看 复制代码
110000        =        \u5317\u4EAC\u5E02
110100        =        \u5317\u4EAC\u5E02\u5E02\u8F96\u533A
110101        =        \u5317\u4EAC\u5E02\u4E1C\u57CE\u533A
110102        =        \u5317\u4EAC\u5E02\u897F\u57CE\u533A
110103        =        \u5317\u4EAC\u5E02\u5D07\u6587\u533A
出生年月日都知道了,还不需要把你的年龄,和从出生到现在多少天算出来。
仅仅知道你多少岁,太没意思了,算出活了XXX日,那才有点儿意思。
年份:好办,当年年份--  出生年份;
月份:当年月份出生月份,有点儿问题,可能出现负数,如果是负数,应该像数学中处理这样的问题一样,年份,去掉一年,月份+12,再减去,出生月份。

日:和月份一样处理的办法,如果,相减是正数,正常处理,负数,加上出生那个月的天数。(好在Calendar这个类处理,得到那个月的天数,很简单
[AppleScript] 纯文本查看 复制代码
        private static int[] data_sub(String id) {
                // TODO Auto-generated method stub
                int[] data = new int[3];
                // 获取出生时的年月日
                int birth_year = Integer.parseInt(id.substring(6, 10));
                int birth_month = Integer.parseInt(id.substring(10, 12));
                int birth_day = Integer.parseInt(id.substring(12, 14));

                // 获取现在时间
                Calendar c = Calendar.getInstance();

                int year = c.get(Calendar.YEAR);
                int month = c.get(Calendar.MONTH) + 1; // 获取的月份是实际月份 +1
                int day = c.get(Calendar.DATE);

                // 计算这个月有多少天
                c.set(year, birth_month + 1, 1); // 下一个月的第一天
                c.add(Calendar.DATE, -1); // 提前一天
                int count_day = c.get(Calendar.DATE);

                // 判断从出生到现在过了多少年月日
                int sub_day;
                int month_sub = 0;
                int year_sub = 0;
                int sub_month;
                int sub_year;

                // 计算过了多少天
                if (day - birth_day >= 0) {
                        sub_day = day - birth_day;

                } else {
                        sub_day = (day + count_day - birth_day);
                        month_sub = 1;
                }

                // 计算过了多少月
                if (month - month_sub - birth_month >= 0) {
                        sub_month = month - month_sub - birth_month;
                } else {
                        sub_month = month + 12 - month_sub - birth_month;
                        year_sub = 1;
                }

                // 计算过多少年
                sub_year = year - year_sub - birth_year;

                // System.out.println("你已经活了" + sub_year + " 年 " + sub_month + " 个月 "
                // + sub_day + " 天");
                data[0] = sub_year;
                data[1] = sub_month;
                data[2] = sub_day;

                return data;
        }
这个倒是好办,不过计算活了多少天,确实存在难题,为什么?
使用SimpleDateFormat这个类呀,解析身份证,时间,转换成long类型的数值,表示出生时的毫秒值,获取当前时间的毫秒值,只要一减,得到数值(不考虑出生时的准确时间),就是从出生到现在时间了(毫秒值)
所以我们常说的UNIX时间戳是以1970110点为计时起点时间的。Integer JAVA内用32位表示,因此32位能表示的最大值是2147483647。另外1365天的总秒数是 315360002147483647/31536000 = 68.1,也就是说32位能表示的最长时间是68年,
资料来源:http://developer.51cto.com/art/201508/488060.htm

也就是说,如果是1970年以后出生的没有问题,可是以前呢。呵呵,就不行了,我暂时没有更好的办法,(我才学习一个多月的java解决不了)也就按照这种办法处理,忽略这个问题吧!
[AppleScript] 纯文本查看 复制代码
        /**
         * 计算出了已经活了多少天了
         * 
         * @param id
         * @return
         * @throws ParseException
         */
        private static int liveDay(String id) throws ParseException {
                // TODO Auto-generated method stub
                SimpleDateFormat sd = new SimpleDateFormat("yyyyMMdd");
                Date d1 = sd.parse(id.substring(6, 14));

                long t1 = d1.getTime();
                long t2 = System.currentTimeMillis();

                int day = (int) ((t2 - t1) / 1000 / 60 / 60 / 24);

                return day;
        }
规则我以前就知道,只是没有用代码实现,昨天花了几个小时去完成代码,完全是自己做的,肯定有不少错误。希望大家帮我改正。多帮助我这个菜鸟,
我把我的源码,上传到附件中。使用eclipse编写的控制台版。和netbeans 7.4 编写的GUI的版本的,可以直接导入使用。









身份证信息解读软件.rar

261.31 KB, 下载次数: 111

修改版

13 个回复

倒序浏览
本帖最后由 L10052108 于 2016-11-10 14:10 编辑

计算从出生到现在有多少天,我没有解决,看你们的了
身份证信息解读软件.rar (261.31 KB, 下载次数: 97)
发现了一处bug,就是月份的时候,少算了一位,
[AppleScript] 纯文本查看 复制代码
// 获取生日信息
        String str = id.substring(6, 10).concat(" 年  ")
                .concat(id.substring(10, 12)).concat(" 月  ")
                .concat(id.substring(12, 14)).concat(" 日  ");
        System.out.println("你的出生日期是:" + str);
由于这一处的错误,如果是10 月,11月份,12月份出生的,就会出现问题
[

回复 使用道具 举报
回复 使用道具 举报
基本数据类型用得很熟啊。。
回复 使用道具 举报
这就是所谓的兴趣使然吧,人才
来自宇宙超级黑马专属苹果客户端来自宇宙超级黑马专属苹果客户端
回复 使用道具 举报
6666,我先收藏一下,有时间再看一下,自己写下,{:8_512:}
回复 使用道具 举报
我就 看啊看那
回复 使用道具 举报
大神啊。。6566
回复 使用道具 举报
回复 使用道具 举报
本帖最后由 L10052108 于 2016-11-14 22:16 编辑

我现在已经发现了好多处的BUG,程序还在完善,有兴趣,帮我一起发现问题,解决他
回复 使用道具 举报
在哪呢?
回复 使用道具 举报

找什么,在哪呢。bug还是,源码
回复 使用道具 举报
源码在哪呢
回复 使用道具 举报
本帖最后由 L10052108 于 2016-11-9 23:34 编辑

快速回复,上面
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马