sub IdentityCardOkay { my $num = shift; my($auth, $idx, $csum1, $lang, $bdate, $csum2, $cdate, $csum3, $csum4) = $num =~ /(\d{4})(\d{5})(\d)(\w)<+(\d{6})(\d)<+(\d{6})(\d)<+(\d)/; croak 'No german identity card!' unless lc($lang) eq "d"; return (CheckSum("$auth$idx") == $csum1 and CheckSum($bdate) == $csum2 and CheckSum($cdate) == $csum3 and CheckSum("$auth$idx$csum1$bdate$csum2$cdate$csum3") == $csum4); } sub CheckSum { my $num = shift; my $len = length($num); my ($n7, $n3, $n1) = (0, 0, 0); for(my $i = 0; $i < $len; $i += 3) { $n7 += substr($num, $i, 1); $n3 += substr($num, $i+1, 1); $n1 += substr($num, $i+2, 1); } return ($n7*7 + $n3*3 + $n1) % 10; }