身份证号校验及属地查询[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 ####################################
阅读(4099) | 评论(0) | 转发(0) |