Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2295796
  • 博文数量: 168
  • 博客积分: 6641
  • 博客等级: 准将
  • 技术积分: 1996
  • 用 户 组: 普通用户
  • 注册时间: 2007-06-02 11:49
文章存档

2020年(4)

2019年(6)

2017年(1)

2016年(3)

2015年(3)

2014年(8)

2013年(2)

2012年(12)

2011年(19)

2010年(10)

2009年(3)

2008年(17)

2007年(80)

分类: LINUX

2008-12-04 21:49:44

身份证号校验及属地查询[Shell脚本]-UTF8版
 
TsengYia#126.com 2008-12-07 http://tsengyia.blog.chinaunix.net/
 
Change Log:
2008.12.07  中文部分改为UTF8字符集,更新地区编码数据库(截至2007.12.31)。
 
文件: idnum_verifier.utf8.tar.bz2
大小: 39KB
下载: 下载
 
#################################################################
 
#!/bin/bash
#*#*#*### 身份证号校验及属地查询[Shell测试版]
#*#*#*### by TsengYia#126.com 2008-12-07 update
#*#*#*### 中文部分编码:zh_CN.UTF-8
#*#*#*### 地区编码数据来源:国家统计局网站
#*#*#*### 档案名称:《最新县及县以上行政区划代码(截止2007年12月31日)》
### ### Part0: 依次指定新、旧版本的地区编码数据库文件
export DB1="AreaCode.db1" DB2="AreaCode.db2"
### ### Part1: 身份证号15<->18位转换函数段
convert1518() {
 ID_NUM=$1
### ### 若输入参数为18位,则转换出15位旧身份证号
 [ ${#ID_NUM} -eq 18 ] && echo "${ID_NUM::6}${ID_NUM:8:9}" && return 0
### ### 若输入参数为15位,则转换出18位新身份证号
### ### 设置校验字串常量及WI数组常量
 declare -r CHK_STR="10X98765432"
 declare -ra WI_ARRAY=(7 9 10 5 8 4 2 1 6 3 7 9 10 5 8 4 2)
### ### 取17位本体码
 TMP_17_NUM=${ID_NUM::6}"19"${ID_NUM:6}
### ### 计算乘积和SUM+=$[AI*WI]
 i=0 ; SUM=0
 while [ $i -lt 17 ] ; do
 let SUM+=$[${TMP_17_NUM:$i:1}*${WI_ARRAY[$i]}]
 let i++ ; done
### ### 取包含正确校验码的18位身份证号
 echo "${TMP_17_NUM}${CHK_STR:$[SUM%11]:1}"
}
### ### Part2: 身份证号有效性验证函数段
verify() {
 ID_NUM=$1
 echo "==== 校验信息 ==== " ;
### ### 1.身份证号位数检查(是否15或18位)
 [ ${#ID_NUM} -ne 15 -a ${#ID_NUM} -ne 18 ] && echo "  ERROR_01 校验失败:输入的身份证号位数不正确。" && return 1
### ### 2.本体码(前17位)数字字符校验
 ( declare -i STR17="8"${ID_NUM::17} ) &> /dev/null
 [ $? -ne 0 ] && echo " ERROR_02 校验失败:本体码部分出现无效字符(非数字)!" && return 1
### ### 设置生日字串截取初始参数(身份证号15位时)
 STEP=0 ; YY_PRE="19"
 if [ ${#ID_NUM} -eq 18 ] ; then
### ### 3.校验位(第18位)正确性检查
### ### 若第18位为小写"x",则转换为大写"X"
  [ ${ID_NUM:17:1} = "x" ] && ID_NUM=${ID_NUM::17}"X"
### ### 重新计算包含正确校验码的18位身份证号
  NEW_18_NUM=$(convert1518 $(convert1518 $ID_NUM))
  [ ${NEW_18_NUM:17:1} != ${ID_NUM:17:1} ] && echo "  ERROR_03 校验失败:校验位(第18位)不正确!" && return 1
### ### 调整生日字串截取参数(身份证号18位时)
  STEP=2 ; YY_PRE=""
 fi
### ### 4.出生日期有效性验证
 BIRTH_NUM=$YY_PRE${ID_NUM:6:$[6+STEP]}
 date -d "$BIRTH_NUM" &> /dev/null
 [ $? -ne 0 ] && echo " ERROR_04 校验失败:无效的出生日期字串!" && return 1
### ### 5.若以上校验无异常,回显校验成功信息
 echo " SUCCEED 校验成功:无明显异常!" ; return 0
}
### ### Part3: 身份证号信息查询函数段(性别/出生日期/籍贯)
inquire() {
 ID_NUM=$1
 verify $ID_NUM ; [ $? -ne 0 ] && echo  -e "==== 身份信息 ==== \n  无效的身份证号!不能获取身份信息!" && return 1
### ### 截取性别/出生日期/地区编码字串
 STEP=2 ; YY_PRE="" ; [ ${#ID_NUM} -eq 15 ] && STEP=0 && YY_PRE="19"
 GENDER_NUM=${ID_NUM:$[14+STEP]:1}
 BIRTH_NUM=${YY_PRE}${ID_NUM:6:$[6+STEP]}
 AREA_NUM=${ID_NUM::6}
### ### 依次输出身份信息(性别/出生日期/籍贯属地)
 echo "==== 身份信息==== "
 GENDER="女"; [ $[GENDER_NUM%2] -eq 1 ] && GENDER="男"
 echo "   性别:$GENDER"
 echo "   出生日期:"$(date -d "$BIRTH_NUM" +"%Y年%m月%d日")
 echo -n "    籍贯属地:"
### ### 在新版地址数据库中查找
 ADD1=$(grep -m 1 "^${AREA_NUM::2}0000" $DB1) && ADD2=$(grep -m 1 "^${AREA_NUM::4}00" $DB1) && ADD3=$(grep -m 1 "^${AREA_NUM}" $DB1)
### ### 若ADD1(省级编码)无结果则返回未知地区
 [ -z "$ADD1" ] && echo '未知地区(或找不到地区码数据库文件)' && return 1
### ### 若ADD2(地区级编码)无结果则返回第一部分地址(省)
 [ -z "$ADD2" ] && echo ${ADD1:7} && return 0
### ### 若ADD3(县级编码)有结果,则返回三个部分的组合地址(省+地+县区)
 [ -n "$ADD3" ] && echo "${ADD1:7} ${ADD2:7} ${ADD3:7}" && return 0
### ### 若ADD3(县级编码)无结果,则在旧版地址数据库中查找
 ADD=$(grep -m 1 "^${AREA_NUM}" $DB2) && echo ${ADD:7} && return 0
### ### 若在旧版地址中找不到结果,则返回第一二部分地址(省+地)
 echo "${ADD1:7} ${ADD2:7}" && return 0
}
### ### Part4: 以下为程序主界面的脚本(Select选择菜单)
MENU=("身份证号信息(性别/生日/属地)查询" "身份证号有效性验证" "身份证号15位-18位转换" "身份证号18位-15位转换" "退出程序")
clear ; echo
echo '*************** 身份证号校验及属地查询[Shell测试版] ***************'
echo '**  by TsengYia#126.com 2008-12-07         **'
echo '**---------------------------------------------------------------**'
echo '** 地区编码数据来源:国家统计局网站       **'
echo '** 档案名称:《最新县及县以上行政区划代码(截止2007年12月31日)》  **'
echo '**---------------------------------------------------------------**'
echo '## 功能菜单:'
### ### 修改菜单提示字串
PS3="请选择操作项> "
select SLT in "${MENU[0]}" "${MENU[1]}" "${MENU[2]}" "${MENU[3]}" "${MENU[4]}"
do
 case $SLT in
  "${MENU[0]}")
### ### 以下为"身份证信息查询"菜单处理
   read -p "请正确输入您的15位或18位身份证号:" ID_NUM
   inquire $ID_NUM
   ;;
  "${MENU[1]}")
### ### 以下为"身份证号有效性校验"菜单处理
   read -p "请正确输入您的15位或18位身份证号:" ID_NUM
   verify $ID_NUM
   ;;
  "${MENU[2]}"|"${MENU[3]}")
### ### 以下为"身份证号18<->15位转换"菜单处理
   LEN=15 ; [ $SLT = ${MENU[3]} ] && LEN=18
   read -p "请正确输入您的$LEN位身份证号:" ID_NUM
   verify $ID_NUM
   [ $? -ne 0 ] && echo -e "==== 转换信息==== \n  输入的身份证号异常!无法进行正确转换!" && continue
   [ ${#ID_NUM} -eq $LEN ] && echo -e "==== 转换信息==== \n  转换后的身份证号是:$(convert1518 $ID_NUM)" && continue
   echo -e "==== 转换信息==== \n  该身份证号不需转换(或无法转换):$ID_NUM"
   ;;
  "${MENU[4]}")
### ### 以下为"退出"菜单处理
   echo "==== 欢迎使用本测试脚本程序。再见!==== "
   exit 0
   ;;
  *)
### ### 以下为"选择项无效"时的处理
   echo " ERROR_00 无效的选择项!直接回车可显示详细菜单(1-5)"
   ;;
 esac
done
 
### ###################### END ####################################
阅读(4149) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~