2

How can I make sure that the given text is Turkish Identity Number? I have seen js version here and phthon version here

Also, posted a question couple of days ago for swift version here.

Turkish Identity Verification is not checks only if its numeric, it has some other functions too. Let me be more clear, It is numeric and has 11 digits. For example Let assume that first 9 digits are represented by d, and the last ones represented by c:

Identity Number = d1 d2 d3 d4 d5 d6 d7 d8 d9 c1 c2

10th digit must be,

c1 = ( (d1 + d3 + d5 + d7 + d9) * 7 - (d2 + d4 + d6 + d8) ) mod10

11th must be,

c2 = ( d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8 + d9 + c1 ) mod10

and it never starts with "0". For example, "87836910956" is a Turkish Identity Number.

Now I have to use this validation in android/java.

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
rozeri dilar
  • 301
  • 1
  • 16

4 Answers4

3

Here is how I ended up:

   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;
rozeri dilar
  • 301
  • 1
  • 16
  • You do not really need a try-catch here, just verify input and return false if input is invalid or try to find the class that fits best to your exceptional event, e.g. throw a `NumberFormatException` instead of the unspecific `Exception.` – Eritrean Dec 04 '18 at 12:34
  • Thanks, you save my hours :) – Yıldırım Sep 27 '19 at 14:01
  • Please DO NOT use that code. It returns false for valid TCK numbers. – az3 Nov 20 '20 at 10:24
1

You could shorten it a little bit without losing readability to:

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;
}
Eritrean
  • 15,851
  • 3
  • 22
  • 28
0

Thanks for all the answers but they all miss something. Builtin Java modulo operator causes a problem for this validation. Builtin Java module operator produces negative modules for negative numbers which causes validation to fail. Instead of using built-in Java module operator, one needs to use Math.floorMod(x, y) method from Math library. That way modulo of a negative number produces positive number which is what expected in the algorithm.

I will share my implementatation:

/*
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;

}

fiver6
  • 161
  • 1
  • 5
-1

Sorry but the code above ( written by Eritrean) is missing some rules. So it does not work.

  • For the short version working code is below ( 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;
        }
    }
    
  • For a longer code but which I believe much more readable in terms of validation rules readability is below ( 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;
    }