Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2263771
  • 博文数量: 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

2007-12-26 14:10:48

身份证号校验及属地查询[Shell测试版]

TsengYia#126.com 2007-12-25  http://selinux.cublog.cn

文件: idcard.rar
大小: 44KB
下载: 下载


###################### Start #######################
#!/bin/bash
#*#*#*### 身份证号校验及属地查询[Shell测试版]
#*#*#*### by TsengYia#126.com 2007-12-25  http://selinux.cublog.cn
#*#*#*### 中文部分编码:zh_CN.GB18030
#*#*#*### 地区编码数据来源:国家统计局网站
#*#*#*### 档案名称:《最新县及县以上行政区划代码(截止2006年12月31日)》

### ### Part0: 依次指定数据库文件名(最新版地址和旧版地址)
export DB1="AreaDB.1st" DB2="AreaDB.2nd"
export LANG="zh_CN.GB18030"

### ### 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 2007-12-25    http://selinux.cublog.cn  **'
echo '**---------------------------------------------------------------**'
echo '** 地区编码数据来源:国家统计局网站       **'
echo '** 档案名称:《最新县及县以上行政区划代码(截止2006年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 #######################
阅读(4567) | 评论(4) | 转发(0) |
给主人留下些什么吧!~~