如何确定给定的文本是土耳其身份证号?我见过js version here和phthon version here
另外,几天前,我对swift version here发表了一个问题。
土耳其语身份验证不仅仅检查其数字,它还具有其他功能。让我更清楚一点,它是数字,有11位数字。例如,假设前9位数字用d表示,后一位数字用c:
表示。Identity Number = d1 d2 d3 d4 d5 d6 d7 d8 d9 c1 c2
第10个数字必须是
c1 = ( (d1 + d3 + d5 + d7 + d9) * 7 - (d2 + d4 + d6 + d8) ) mod10
必须是11号,
c2 = ( d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8 + d9 + c1 ) mod10
,且永远不会以“ 0”开头。例如,“ 87836910956”是土耳其身份证号码。
现在我必须在android / java中使用此验证。
答案 0 :(得分:4)
这就是我的结局:
private static boolean verifyNumber(String nationalityNumberStr) {
try {
String tmp = nationalityNumberStr;
if(tmp.toCharArray()[0] != '0'){
//cannot start with 0
if (tmp.length() == 11) {
//should be 11 digits
int totalOdd = 0;
int totalEven = 0;
for (int i = 0; i < 9; i++) {
int val = Integer.valueOf(tmp.substring(i, i + 1));
if (i % 2 == 0) {
totalOdd += val;
} else {
totalEven += val;
}
}
int total = totalOdd + totalEven + Integer.valueOf(tmp.substring(9, 10));
int lastDigit = total % 10;
if (tmp.substring(10).equals(String.valueOf(lastDigit))) {
int check = (totalOdd * 7 - totalEven) % 10;
if (tmp.substring(9, 10).equals(String.valueOf(check))) {
return true;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
return false;
答案 1 :(得分:1)
您可以在不降低可读性的情况下将其缩短一点:
private static boolean verifyNumber(String nationalityNumberStr) {
if(nationalityNumberStr.startsWith("0") || !nationalityNumberStr.matches("[0-9]{11}") ){
return false;
}
int [] temp = new int [11];
for (int i = 0; i < 11; i++){
temp[i] = Character.getNumericValue(nationalityNumberStr.toCharArray()[i]);
}
int c1 = 0;
int c2 = temp[9];
for(int j = 0; j < 9; j++){
if(j%2 == 0) {
c1 += temp[j] * 7;
}
else {
c1 -= temp[j];
}
c2 += temp[j];
}
return temp[9]== c1 % 10 && temp[10] == c2 %10;
}
答案 2 :(得分:0)
对不起,但是上面的代码(written by Eritrean)缺少某些规则。因此它不起作用。
简短版本的工作代码如下( C#):
public static bool IsValidTcknShortCode(string tckn)
{
int internalSum = 0, sumFirst9Digit = 0, sumFirst10Digit = 0, current = 0, tckn10thDigit, tcknLastDigit;
try
{
if (tckn.Length != 11 || !tckn.All(char.IsDigit) || tckn.Substring(0, 1) == "0")
return false;
for (int i = 1; i < tckn.Length - 1; i++)
{
current = int.Parse(tckn[i - 1].ToString());
if (i % 2 != 0)
internalSum += (current * 7);
else
internalSum -= current;
sumFirst9Digit += current;
}
tckn10thDigit = int.Parse(tckn[9].ToString());
tcknLastDigit = int.Parse(tckn[10].ToString());
sumFirst10Digit = sumFirst9Digit + tckn10thDigit;
return (internalSum % 10 == tckn10thDigit && sumFirst10Digit % 10 == tcknLastDigit);
}
catch (Exception ex)
{
string exMessage = ex.Message;
return false;
}
}
对于更长的代码,但我相信根据验证规则更具可读性 可读性在下面( C#);
public static bool IsValidTckn(string tckn)
{
int sum13579 = 0, sum2468 = 0, sumFirst10Digit = 0, current = 0, tckn10thDigit, tcknLastDigit;
try
{
// TC Kimlik numaraları 11 basamaktan oluşmaktadır.
if (tckn.Length != 11)
throw new ArgumentException("Length of TCKN must equal to 11");
// Her hanesi rakamsal değer içerir.
if (!tckn.All(char.IsDigit))
throw new ArgumentException("TCKN must only consists of numeric values");
// İlk hane 0 olamaz
if (tckn.Substring(0, 1) == "0")
throw new ArgumentException("TCKN must not start with 0");
for (int i = 1; i < tckn.Length - 1; i++)
{
current = int.Parse(tckn[i - 1].ToString());
if (i % 2 == 0)
sum2468 += current;
else
sum13579 += current;
}
tckn10thDigit = int.Parse(tckn[9].ToString());
sumFirst10Digit = sum13579 + sum2468 + tckn10thDigit;
// 1. 3. 5. 7. ve 9. hanelerin toplamının 7 katından, 2. 4. 6. ve 8. hanelerin toplamı çıkartıldığında, elde edilen sonucun Mod 10’u bize 10. haneyi verir.
if (((sum13579 * 7) - sum2468) % 10 != tckn10thDigit)
throw new ArgumentException("Not Valid TCKN");
tcknLastDigit = int.Parse(tckn[10].ToString());
// 1. 2. 3. 4. 5. 6. 7. 8. 9. ve 10. hanelerin toplamından elde edilen sonucun 10’a bölümünden kalan, yani Mod10’u bize 11. haneyi verir.
if (sumFirst10Digit % 10 != tcknLastDigit)
throw new ArgumentException("Not Valid TCKN");
}
catch (Exception ex)
{
string exMessage = ex.Message;
return false;
}
return true;
}
答案 3 :(得分:0)
感谢所有的答案,但他们都错过了一些东西。内置 Java 模运算符会导致此验证出现问题。内置 Java 模块运算符为负数生成负模块,从而导致验证失败。不需要使用内置的 Java 模块运算符,而是需要使用 Math 库中的 Math.floorMod(x, y) 方法。这样,负数的模产生正数,这正是算法中所期望的。
我将分享我的实现:
/*
Tc No = d1 d2 d3 d4 d5 d6 d7 d8 d9 c1 c2
c1 = ( (d1 + d3 + d5 + d7 + d9) * 7 - (d2 + d4 + d6 + d8) ) mod10
c2 = ( d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8 + d9 + c1 ) mod10
*/
public static boolean isValidIdentityNumber(String identityNumber) {
int d1 = Character.getNumericValue(identityNumber.charAt(0));
int d2 = Character.getNumericValue(identityNumber.charAt(1));
int d3 = Character.getNumericValue(identityNumber.charAt(2));
int d4 = Character.getNumericValue(identityNumber.charAt(3));
int d5 = Character.getNumericValue(identityNumber.charAt(4));
int d6 = Character.getNumericValue(identityNumber.charAt(5));
int d7 = Character.getNumericValue(identityNumber.charAt(6));
int d8 = Character.getNumericValue(identityNumber.charAt(7));
int d9 = Character.getNumericValue(identityNumber.charAt(8));
int d10 = Character.getNumericValue(identityNumber.charAt(9));
int d11 = Character.getNumericValue(identityNumber.charAt(10));
int c1 = Math.floorMod((d1 + d3 + d5 + d7 + d9) * 7 - (d2 + d4 + d6 + d8), 10);
int c2 = Math.floorMod(d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8 + d9 + c1, 10);
return c1 == d10 && c2 == d11;
}