Perl練習之驗證身份證程序

近來對Perl有點興趣,就寫了個小程序,剛好有軟工作業,於是分別用白黑盒測試了下,效果還是不錯的!!!以後寫網頁表單驗證可以用到。


說明下,身份證分一代證15位與二代證18位,其中前六位地區碼,(這個沒有驗證)18位多的就是年份是四位,15位的年份兩位,前兩位默認爲“19”,18位的最後一位爲校驗碼,具體算法請看程序,其中前17位每一位都有權值,算出總和後模11算出對應的校驗碼即可。

更多說明請Google之。。。

其中帶#標記的是用來標記白盒測試路徑點,不知道是否合理,但是,一個正則表達式就搞定很多情況啊!!!大笑


其中輸入爲,相信是看得懂的^_^

./cardValidate.pl -c [your id card number] -s [your sex]


#!/usr/bin/perl
use strict;
use Getopt::Long;

sub validate_birth{
    my ($year,$month,$day) = @_;
    if($year lt 1900 or $year gt 2011){#9 10
    	die "Bitrhday error year!\n";
    }
    if($month eq "00" or $month gt 12){#11 12
    	die "Bitrhday error month!\n";
    }
    my %days = (
            "01" => 31,
            "03" => 31,
            "04" => 30,
            "05" => 31,
            "06" => 30,
            "07" => 31,
            "08" => 31,
            "09" => 30,
            "10" => 31,
            "11" => 30,
            "12" => 31
            );
    if($year % 400 eq 0 or ($year % 4 eq 0 and $year % 100 ne 0)){#13 #14
        $days{"02"} = 28;        
    }else{#16
        $days{"02"} = 29;
    }
    if($days{$month} lt $day or $day eq "00"){#17 #18
        die "Bitrhday error date!\n";
    }
    return 1;
}

###################        begin         ######################
our $code;
our $sex;

GetOptions("c=s" => \$code,"s=s" => \$sex);#1

if($code eq "" or $sex eq ""){#2 3
    print "Usage: ./cardValidate.pl -c [your id card number] -s [your sex]\n";
    die "\tNote: the length of your id number should be 15 or 18\n";
}

our $code_len = length $code;#4

##################   basic rule and length   ##################
if($code !~ m/(^\d{15}$)|(\d{17}(\d|x|X)$)/){#5
    die "Error code!\n";
}

###################  birthday and sex  ######################
my $sex_num;
if($code_len eq 15){#6
    &validate_birth("19".substr($code,6,2),substr($code,8,2),substr($code,10,2));#8
    $sex_num = substr($code,14,1) % 2; 
}elsif($code_len eq 18){#7
    &validate_birth(substr($code,6,4),substr($code,10,2),substr($code,12,2));#8
    $sex_num = substr($code,16,1) % 2;
    
    #################  validate last character   ##################
    my @wight = (7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2);#權值
    my @validate = ('1','0','x','9','8','7','6','5','4','3','2');#對應的校驗碼
    my $sum = 0;
    for(my $i = 0;$i < 17;$i++){
        $sum += @wight[$i] * substr($code,$i,1);
    }
    if(@validate[$sum % 11] ne lc substr($code,17,1)){#19
        die "Error while validate the last character!,it should be ".@validate[$sum % 11]."\n";
    }
}

#################        sex           ######################
if(($sex_num eq 1 and $sex eq "女") or ($sex_num eq 0 and $sex eq "男")){#20 21
    die "Wrong sex number!\n";
}

print "Success!\n";#22


然後是用來測試的程序:

將身份證號碼與0表示女,1表示男輸入到文件中,比如:”7837838484884 0“ 就可以

每行一條數據,然後將文件名當作參數傳入即可,當然,上面的程序需要放在同目錄下。於是白黑盒測試的數據可以放一起全部測試

#!/usr/bin/perl
use strict;

open FILE,"< ",$ARGV[0] or die "id file not exist!\n";
my @lines = <FILE>;
foreach(@lines){
    if(~/^([\w\d]+) (\d)/){
        my $sex = ($2 eq 0?"女":"男");
        print "Test $1 with sex $sex\n";
        system("./cardValidate.pl -c $1 -s $sex");
        print "\n";
    }
}

我想,腳本的魅力就是簡潔高效吧,如果我用C去寫,白盒測試可真是要命啊!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章