Bir TC Kimlik Numarası’nın algoritmik olarak geçerli olup olmadığını kontrol etmek, yazılım geliştirmede en sık karşılaşılan form doğrulama (validation) işlemlerinden biridir. Bu makalede, TC Kimlik Numarası algoritmasının 10. ve 11. hane kontrol kurallarını beş farklı programlama dilinde nasıl uygulayacağınızı göstereceğiz.

Doğrulama mantığı tüm dillerde aynıdır — tek sıradaki hanelerin toplamının 7 katından çift sıradaki hanelerin toplamını çıkarıp mod 10 alarak 10. haneyi, ilk 10 hanenin toplamının mod 10’unu alarak 11. haneyi kontrol ederiz. Ancak her dilin sunduğu araçlar (yerleşik fonksiyonlar, tip güvenliği, string işleme yetenekleri) farklı olduğu için uygulama detayları da farklılık gösterir.

Doğrulama Mantığı Özeti

TC Kimlik Numarası 11 haneden oluşur ve şu kurallara uyar:

  1. 11 haneli olmalıdır ve yalnızca rakamlardan oluşmalıdır
  2. İlk hane sıfır (0) olamaz
  3. 10. hane kontrolü: (d₁+d₃+d₅+d₇+d₉) × 7 − (d₂+d₄+d₆+d₈) işleminin 10’a göre modülüsü 10. haneye eşit olmalıdır
  4. 11. hane kontrolü: İlk 10 hanenin toplamının 10’a göre modülüsü 11. haneye eşit olmalıdır

Bu kuralların matematiksel detayı ve çalışan örnek için algoritma sayfamızı ziyaret edebilirsiniz. Aşağıda her programlama dili için bu kuralları uygulayan tam fonksiyonları bulacaksınız.


PHP ile TC Kimlik No Doğrulama

PHP, web geliştirmede TC Kimlik No doğrulama ihtiyacının en sık ortaya çıktığı dillerden biridir. PHP’nin yerleşik ctype_digit() fonksiyonu, bir string’in yalnızca rakamlardan oluşup oluşmadığını kontrol etmekte son derece etkilidir ve regex kullanmaktan daha hızlıdır. Ayrıca array_map, array_sum ve array_slice fonksiyonları, dizi işlemlerini tek satırlarda halletmemizi sağlar.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
function validateTCNumber($tckn) {
    // TC Kimlik numarası 11 haneli olmalıdır
    if (strlen($tckn) != 11) {
        return false;
    }
    
    // TC Kimlik numarası sadece rakamlardan oluşmalıdır
    if (!ctype_digit($tckn)) {
        return false;
    }
    
    // İlk hane 0 olamaz
    if ($tckn[0] == '0') {
        return false;
    }
    
    $digits = array_map('intval', str_split($tckn));
    
    // 10. hane kontrolü
    $digit10 = ((array_sum(array_slice($digits, 0, 9, 2)) * 7) - array_sum(array_slice($digits, 1, 8, 2))) % 10;
    if ($digit10 != $digits[9]) {
        return false;
    }
    
    // 11. hane kontrolü
    $digit11 = array_sum(array_slice($digits, 0, 10)) % 10;
    if ($digit11 != $digits[10]) {
        return false;
    }
    
    return true;
}

// Test örnekleri
$test_numbers = [
    "10000000146",  // Geçerli
    "12345678901",  // Geçersiz
    "1234",         // Geçersiz (11 haneli değil)
    "02345678901"   // Geçersiz (ilk hane 0)
];

foreach ($test_numbers as $tckn) {
    $result = validateTCNumber($tckn);
    echo "$tckn: " . ($result ? "Geçerli" : "Geçersiz") . "\n";
}

Laravel’de kullanım: Bu fonksiyonu bir Validation Rule sınıfına sararak form request’lerinde şık bir şekilde kullanabilirsiniz:

// app/Rules/ValidTCNumber.php
class ValidTCNumber implements ValidationRule
{
    public function validate(string $attribute, mixed $value, Closure $fail): void
    {
        if (!validateTCNumber($value)) {
            $fail('Geçersiz TC Kimlik Numarası.');
        }
    }
}

// Form Request'te kullanım
public function rules(): array
{
    return [
        'tc_kimlik_no' => ['required', 'string', new ValidTCNumber()],
    ];
}

Python ile TC Kimlik No Doğrulama

Python, syntax’ın okunabilirliği ve list comprehension’ların gücü sayesinde TC Kimlik No doğrulama algoritmasını en net şekilde ifade edebilen dillerden biridir. str.isdigit() metodu tip kontrolü için yeterlidir; dilimleme (slicing) ve adımlı (step) slicing (digits[0:9:2]) ise tek sıradaki ve çift sıradaki haneleri ayrıştırmayı tek satırda yapar.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
def validate_tc_number(tckn: str) -> bool:
    # TC Kimlik numarası 11 haneli olmalıdır
    if not len(tckn) == 11:
        return False
    
    # TC Kimlik numarası sadece rakamlardan oluşmalıdır
    if not tckn.isdigit():
        return False
    
    # İlk hane 0 olamaz
    if tckn[0] == '0':
        return False
    
    digits = [int(d) for d in tckn]
    
    # 10. hane kontrolü: (tek sıra toplamı × 7 - çift sıra toplamı) mod 10
    odd_sum = sum(digits[0:9:2])   # d1, d3, d5, d7, d9
    even_sum = sum(digits[1:8:2])  # d2, d4, d6, d8
    digit10 = (odd_sum * 7 - even_sum) % 10
    
    if digit10 != digits[9]:
        return False
    
    # 11. hane kontrolü: ilk 10 hanenin toplamının mod 10
    digit11 = sum(digits[:10]) % 10
    
    if digit11 != digits[10]:
        return False
    
    return True

# Test örnekleri
test_numbers = [
    "10000000146",  # Geçerli
    "12345678901",  # Geçersiz
    "1234",         # Geçersiz (11 haneli değil)
    "02345678901"   # Geçersiz (ilk hane 0)
]

for tckn in test_numbers:
    result = validate_tc_number(tckn)
    print(f"{tckn}: {'Geçerli' if result else 'Geçersiz'}")

Django’da kullanım: Django’da bu fonksiyonu bir form field doğrulayıcısı olarak kaydedebilirsiniz:

# validators.py
from django.core.exceptions import ValidationError

def validate_tc_number(tckn):
    if not validate_tc_number(tckn):
        raise ValidationError("Geçersiz TC Kimlik Numarası.")

# forms.py
from django import forms
from .validators import validate_tc_number as tc_validator

class UserProfileForm(forms.Form):
    tc_kimlik_no = forms.CharField(
        max_length=11,
        validators=[tc_validator],
        label="TC Kimlik Numarası"
    )

JavaScript ile TC Kimlik No Doğrulama

JavaScript’te TC Kimlik No doğrulama, hem tarayıcı tarafında hem de Node.js ortamında çalışır. Tarayıcıda, kullanıcı formu göndermeden önce anında geri bildirim sağlayarak kullanıcı deneyimini iyileştirir. filter() ve reduce() metotları ile fonksiyonel bir yaklaşım benimsenir; regex (/^[0-9]+$/) ise tip kontrolü için kullanılır.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
function validateTCNumber(tckn) {
    // TC Kimlik numarası 11 haneli olmalıdır
    if (tckn.length !== 11) {
        return false;
    }
    
    // TC Kimlik numarası sadece rakamlardan oluşmalıdır
    if (!/^[0-9]+$/.test(tckn)) {
        return false;
    }
    
    // İlk hane 0 olamaz
    if (tckn[0] === '0') {
        return false;
    }
    
    const digits = Array.from(tckn).map(Number);
    
    // 10. hane kontrolü
    const oddSum = digits[0] + digits[2] + digits[4] + digits[6] + digits[8];
    const evenSum = digits[1] + digits[3] + digits[5] + digits[7];
    const digit10 = (oddSum * 7 - evenSum) % 10;
    
    if (digit10 !== digits[9]) {
        return false;
    }
    
    // 11. hane kontrolü
    const digit11 = digits.slice(0, 10).reduce((a, b) => a + b, 0) % 10;
    
    if (digit11 !== digits[10]) {
        return false;
    }
    
    return true;
}

// Test örnekleri
const testNumbers = [
    "10000000146",  // Geçerli
    "12345678901",  // Geçersiz
    "1234",         // Geçersiz (11 haneli değil)
    "02345678901"   // Geçersiz (ilk hane 0)
];

testNumbers.forEach(tckn => {
    const result = validateTCNumber(tckn);
    console.log(`${tckn}: ${result ? "Geçerli" : "Geçersiz"}`);
});

Tarayıcıda form entegrasyonu: Bu fonksiyonu bir HTML formunun submit olayına bağlayarak sunucuya istek gitmeden önce doğrulama yapabilirsiniz:

document.querySelector('#tcForm').addEventListener('submit', function(e) {
    const tcInput = document.querySelector('#tcInput').value;
    if (!validateTCNumber(tcInput)) {
        e.preventDefault();
        alert('Lütfen geçerli bir TC Kimlik Numarası giriniz.');
    }
});

Java ile TC Kimlik No Doğrulama

Java’nın statik tip sistemi, TC Kimlik No doğrulama mantığını kurumsal uygulamalarda (Spring Boot, Java EE) güvenli bir şekilde uygulanmasını sağlar. Java’da regex ile tip kontrolü yapılır (String.matches("^[0-9]+$")), döngülerle haneler ayrıştırılır. Kotlin, Scala veya Kotlin/Java karışık projelerde de aynı mantık kullanılabilir.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
public class TCKimlikNoValidator {
    public static boolean validateTCNumber(String tckn) {
        // TC Kimlik numarası 11 haneli olmalıdır
        if (tckn.length() != 11) {
            return false;
        }
        
        // TC Kimlik numarası sadece rakamlardan oluşmalıdır
        if (!tckn.matches("^[0-9]+$")) {
            return false;
        }
        
        // İlk hane 0 olamaz
        if (tckn.charAt(0) == '0') {
            return false;
        }
        
        int[] digits = new int[11];
        for (int i = 0; i < 11; i++) {
            digits[i] = Character.getNumericValue(tckn.charAt(i));
        }
        
        // 10. hane kontrolü
        int sumOdd = digits[0] + digits[2] + digits[4] + digits[6] + digits[8];
        int sumEven = digits[1] + digits[3] + digits[5] + digits[7];
        int digit10 = (sumOdd * 7 - sumEven) % 10;
        
        if (digit10 != digits[9]) {
            return false;
        }
        
        // 11. hane kontrolü
        int sum = 0;
        for (int i = 0; i < 10; i++) {
            sum += digits[i];
        }
        int digit11 = sum % 10;
        
        if (digit11 != digits[10]) {
            return false;
        }
        
        return true;
    }

    public static void main(String[] args) {
        String[] testNumbers = {
            "10000000146",  // Geçerli
            "12345678901",  // Geçersiz
            "1234",         // Geçersiz (11 haneli değil)
            "02345678901"   // Geçersiz (ilk hane 0)
        };

        for (String tckn : testNumbers) {
            boolean result = validateTCNumber(tckn);
            System.out.println(tckn + ": " + (result ? "Geçerli" : "Geçersiz"));
        }
    }
}

Spring Boot’ta kullanım: Spring’de bir @Constraint annotation’ı oluşturarak bu doğrulamayı Bean Validation çerçevesine entegre edebilirsiniz:

// Custom annotation ve validator
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = TCNumberValidator.class)
public @interface ValidTCNumber {
    String message() default "Geçersiz TC Kimlik Numarası";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

public class TCNumberValidator implements ConstraintValidator<ValidTCNumber, String> {
    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        return value != null && TCKimlikNoValidator.validateTCNumber(value);
    }
}

Go ile TC Kimlik No Doğrulama

Go’nun minimal ve performans odaklı tasarımı, TC Kimlik No doğrulama fonksiyonunu son derece verimli hale getirir. Go’da regexp.MatchString ile tip kontrolü yapılır, dilim işlemleri (slice) ile haneler ayrıştırılır. Go’nun statik tip güvenliği ve derlenmiş doğası, bu fonksiyonu yüksek trafikli API servislerinde gönül rahatlığıyla kullanmanızı sağlar.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package main

import (
    "fmt"
    "regexp"
    "strconv"
)

func validateTCNumber(tckn string) bool {
    // TC Kimlik numarası 11 haneli olmalıdır
    if len(tckn) != 11 {
        return false
    }
    
    // TC Kimlik numarası sadece rakamlardan oluşmalıdır
    matched, _ := regexp.MatchString("^[0-9]+$", tckn)
    if !matched {
        return false
    }
    
    // İlk hane 0 olamaz
    if tckn[0] == '0' {
        return false
    }
    
    digits := make([]int, 11)
    for i := 0; i < 11; i++ {
        digits[i], _ = strconv.Atoi(string(tckn[i]))
    }
    
    // 10. hane kontrolü
    sumOdd := digits[0] + digits[2] + digits[4] + digits[6] + digits[8]
    sumEven := digits[1] + digits[3] + digits[5] + digits[7]
    digit10 := (sumOdd*7 - sumEven) % 10
    
    if digit10 != digits[9] {
        return false
    }
    
    // 11. hane kontrolü
    sum := 0
    for i := 0; i < 10; i++ {
        sum += digits[i]
    }
    digit11 := sum % 10
    
    if digit11 != digits[10] {
        return false
    }
    
    return true
}

func main() {
    testNumbers := []string{
        "10000000146",  // Geçerli
        "12345678901",  // Geçersiz
        "1234",         // Geçersiz (11 haneli değil)
        "02345678901",  // Geçersiz (ilk hane 0)
    }

    for _, tckn := range testNumbers {
        result := validateTCNumber(tckn)
        if result {
            fmt.Printf("%s: Geçerli\n", tckn)
        } else {
            fmt.Printf("%s: Geçersiz\n", tckn)
        }
    }
}

Gin veya Echo’da kullanım: Go web çatılarında bu fonksiyonu bir middleware veya handler içinde çağırabilirsiniz:

func validateTCMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        tcNo := c.PostForm("tc_kimlik_no")
        if !validateTCNumber(tcNo) {
            c.JSON(http.StatusBadRequest, gin.H{"error": "Geçersiz TC Kimlik Numarası"})
            c.Abort()
            return
        }
        c.Next()
    }
}

Sıkça Sorulan Sorular

S: Bu doğrulama fonksiyonu gerçek bir TC Kimlik Numarasını garanti eder mi?

Hayır. Bu fonksiyon yalnızca numaranın algoritmik olarak geçerli olup olmadığını kontrol eder — yani 10. ve 11. hanelerin doğru hesaplandığını. Numaranın gerçekten bir vatandaşa ait olduğunu doğrulamak için e-Devlet üzerinden NVİ’nin resmi servisini kullanmanız gerekir.

S: Hangi programlama dilini seçmeliyim?

Projenizin kullandığı dile bağlıdır. Eğer bir REST API geliştiriyorsanız Python/Flask, PHP/Laravel veya Go/Gin tercih edebilirsiniz. Tarayıcı tarafında anlık doğrulama için JavaScript versiyonunu kullanın. Her versiyon aynı matematiksel sonucu üretir.

S: Tüm dillerde aynı test numarasını kullanabilir miyim?

Evet, 10000000146 örneği tüm dillerde “Geçerli” sonucunu döndürür ve herhangi bir gerçek kişiye ait olduğu garanti edilmeyen bir test numarasıdır.

S: Doğrulama başarısız olursa kullanıcıya nasıl mesaj göstermeliyim?

Doğrulama başarısız olduğunda kullanıcıya spesifik bir mesaj gösterin: “Girdiğiniz TC Kimlik Numarası 11 haneli olmalıdır” veya “TC Kimlik Numarası geçersiz — lütfen kontrol ediniz”. Genel bir “hata” mesajı yerine, hatanın nedenini açıklayan mesajlar kullanıcı deneyimini iyileştirir.


İlgili İçerikler


Bu makalede verilen kod örnekleri eğitim ve test amaçlıdır. Gerçek TC Kimlik Numaralarıyla çalışırken kişisel verilerin korunması kanunlarına (KVKK) dikkat ediniz.