TC Kimlik No Algoritması ve hesaplaması

Merhabalar sevgili okurlarım, gerçeği söylemek gerekirse okurum olabilecek bir içeriğim yok. Bunun farkındayım, daha çok googlayanlaya yönelik bilgi kaynağım mevcut tabi.

Düşük cümleler kuruyorsam affola. Yavaş yavaş Türkçe karakterleri kullanmaya çalışıyorum.

Bir önceki yazımda IMEI ve Kredi kartı gibi verilerin kontrolünde kullanılan algoritmayı paylaşmıştım. Luhn Check digit Mode 10 algoritması Bu yazımda da T.C. kimlik numarasının 10. ve 11. hanelerini hesaplayacağız.

Öncelik ile tc kimlik no Türkiye Cumhuriyeti vatandaşlarının kimliklerine verilen ID (identification) numaralarıdır. Devlet dairelerinde, bankalarda ve bir çok noktada güvenlik ve kimlik tanımlama işlemi için kullanılır. T.C. veri tabanında sorgulamak için belirli anlaşmalar yapmanız ve ücretini ödemeniz gerekmektedir. T.C. Kimlik No o kişiye ait mi bunun kontrolünü direk siz yapamazsınız fakat Numara kurallara uygun mu buna bakarsınız; Bunun için gerekli bilgiler :
  1. TC Kimlik numaraları 11 basamaktan oluşmaktadır.
  2.  İlk 9 basamak arasında kurulan bir algoritma bize 10. basmağı, ilk 10 basamak arasında kurulan algoritma ise bize 11. basamağı verir.
  3.  11 hanelidir.
  4. Her hanesi rakamsal değer içerir.
  5.  İlk hane 0 olamaz.
  6. Son hane tek sayi (1,3,5,7,9) olamaz
  7. 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 10′a bölümünden kalan, yani Mod10′u bize 10. haneyi verir.
  8. 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.
  9. 10. hanenin hesaplama şekline göre çift bir sayının 10’a bölümü çift, tek bir sayının 10’a bölümü tek sayı olur. 2 adet çift sayının toplamı çift, 2 adet tek sayının toplamı çift sonuç verir. Bu sonuça göre Son hane her zaman çifttir. 

Şimdi gelelim farklı dillerdeki doğrulama örneklerine.

C#

public static bool TcDogrulaV2(string tcKimlikNo)
{
    bool returnvalue = false;
    if (tcKimlikNo.Length == 11)
    {
        Int64 ATCNO, BTCNO, TcNo;
        long C1,C2,C3, C4, C5,C6,C7,C8, C9,Q1,Q2;
 
        TcNo = Int64.Parse(tcKimlikNo);

	// bolu yuz islemi int tanimlanmis degiskende son 2 haneyi silmek icin kullanılır.
 
        ATCNO = TcNo / 100;
        BTCNO = TcNo / 100;
 
         C1 = ATCNO % 10;  ATCNO = ATCNO / 10 ;
         C2 = ATCNO % 10;  ATCNO = ATCNO / 10 ;
         C3 = ATCNO % 10;  ATCNO = ATCNO / 10 ;
         C4 = ATCNO % 10;  ATCNO = ATCNO / 10 ;
         C5 = ATCNO % 10;  ATCNO = ATCNO / 10 ;
         C6 = ATCNO % 10;  ATCNO = ATCNO / 10 ;
         C7 = ATCNO % 10;  ATCNO = ATCNO / 10 ;
         C8 = ATCNO % 10;  ATCNO = ATCNO / 10 ;
         C9 = ATCNO % 10;  ATCNO = ATCNO / 10 ;
         Q1 = ((10-((((C1+C3+C5+C7+C9)*3)+(C2+C4+C6+C8))%10))%10);
         Q2 = ((10-(((((C2+C4+C6+C8)+Q1)*3)+(C1+C3+C5+C7+C9))%10))%10);

         /*
         Q1 TC nosunun 10. hanesi
         Q2 TC nosunun 11. hanesi
         BTCNO son 2 hanesi olmayan tckimlikNo
         */ 

         returnvalue = ((BTCNO * 100)+(Q1 * 10)+Q2 == TcNo);
    }
    return returnvalue;
}

Vb.Net

Function TcDogrulaV2(ByVal tcKimlikNo As String) As Boolean
    Dim returnvalue As Boolean = False
    If (tcKimlikNo.Length <> 11) Then
        tcCustom.ErrorMessage = "<br>TC Kimlik Numarası 11 Haneli Olmalıdır."
        Return returnvalue
    End If
    Dim TcNo As Long = Long.Parse(tcKimlikNo)
    Dim BTCNO As Long = Long.Parse(Left(tcKimlikNo, 9))
         
    Dim C1 As Long = Long.Parse(Mid(tcKimlikNo, 1, 1))
    Dim C2 As Long = Long.Parse(Mid(tcKimlikNo, 2, 1))
    Dim C3 As Long = Long.Parse(Mid(tcKimlikNo, 3, 1))
    Dim C4 As Long = Long.Parse(Mid(tcKimlikNo, 4, 1))
    Dim C5 As Long = Long.Parse(Mid(tcKimlikNo, 5, 1))
    Dim C6 As Long = Long.Parse(Mid(tcKimlikNo, 6, 1))
    Dim C7 As Long = Long.Parse(Mid(tcKimlikNo, 7, 1))
    Dim C8 As Long = Long.Parse(Mid(tcKimlikNo, 8, 1))
    Dim C9 As Long = Long.Parse(Mid(tcKimlikNo, 9, 1))
         
    Dim Q1 As Long = ((10 - (((((((C1 + C3) + C5) + C7) + C9) * 3) + (((C2 + C4) + C6) + C8)) Mod 10)) Mod 10)
    Dim Q2 As Long = ((10 - (((((((C2 + C4) + C6) + C8) + Q1) * 3) + ((((C1 + C3) + C5) + C7) + C9)) Mod 10)) Mod 10)
    'Response.Write((((BTCNO * 100) + (Q1 * 10)) + Q2) & " - ")
    'Response.Write(tcKimlikNo)
    If ((((BTCNO * 100) + (Q1 * 10)) + Q2) = TcNo) Then
        tcCustom.ErrorMessage = ""
    Else
        tcCustom.ErrorMessage = "<br>Hatalı TC Kimlik Numarası."
    End If
       
    Return ((((BTCNO * 100) + (Q1 * 10)) + Q2) = TcNo)
End Function

Javascript

function check_tcno(a){
  if(a.substr(0,1)==0&&a.lenght!=11){
    return false;
  }
  var i = 9, md='', mc='', digit, mr='';
  while(digit = a.charAt(--i)){
    i%2==0 ? md += digit : mc += digit;
  }
  if(((eval(md.split('').join('+'))*7)-eval(mc.split('').join('+')))%10!=parseInt(a.substr(9,1),10)){
    return false;
  }
  for (c=0;c<=9;c++){
    mr += a.charAt(c);
  }
  if(eval(mr.split('').join('+'))%10!=parseInt(a.substr(10,1),10)){
    return false;
  }
  return true;
}

PHP

// with pattern
function check_tcno($tcno) {
        preg_replace('/([1-9]{1})([0-9]{1})([0-9]{1})([0-9]{1})([0-9]{1})([0-9]{1})([0-9]{1})([0-9]{1})([0-9]{1}).*$/e', "eval('\$on=((((\\1+\\3+\\5+\\7+\\9)*7)-(\\2+\\4+\\6+\\8))%10); \$onbir=(\\1+\\2+\\3+\\4+\\5+\\6+\\7+\\8+\\9+\$on)%10; \$sonIki = \$on.\$onbir;')", $tcno);
        return(substr($tcno, -2) == $sonIki);
}

// spagetti
function _tcNoCheck($tcNo){
    // For Controller
    $isDouble = is_double($tcNo);
    $size     = strlen($tcNo);
    $type     = gettype($tcNo);
              
    // First Controller
    if($tcNo == "" || $tcNo == null || $tcNo == 0){
        return false; //Bu alan boş bırakılamaz!
    }else if($size != 11 && $type != "integer"){            
        // Data Type Size Controller
        return false; //T.C. kimlik no 11 haneli olmak zorundadır!
    }else if($type == "integer"){
        // Type convert controller
        return false; //T.C. kimlik no 0(sıfır) ile başlayamaz ve 11 hane olmak zorundadır!
    }else if($isDouble != true) {
        // Data Type Controller
        return false; //T.C. kimlik no sadece sayısal girilmelidir!
    }else{
        // TC NO's
        $tc1;$tc2;$tc3;$tc4;$tc5;$tc6;
        $tc7;$tc8;$tc9;$tc10;$tc11;
              
        $tc1 = substr($tcNo,0,1);
        $tc2 = substr($tcNo,1,1);
        $tc3 = substr($tcNo,2,1);
        $tc4 = substr($tcNo,3,1);
        $tc5 = substr($tcNo,4,1);
        $tc6 = substr($tcNo,5,1);
        $tc7 = substr($tcNo,6,1);
        $tc8 = substr($tcNo,7,1);
        $tc9 = substr($tcNo,8,1);
        $tc10 = substr($tcNo,9,1);
        $tc11 = substr($tcNo,10,1);
  
        //First Algo. Checks
        $algoCheck1 = (($tc1 + $tc3 + $tc5 + $tc7 + $tc9) * 7);
        $algoCheck2 = abs(((($tc2 + $tc4 + $tc6 + $tc8) - $algoCheck1) % 10));
        $algoCheck3 = (($tc1 + $tc2 + $tc3 + $tc4 + $tc5 + $tc6 + $tc7 + $tc8 + $tc9 + $tc10) % 10); 
                  
        if($algoCheck2 != $tc10){
            return false; //Geçersiz T.C. kimlik no!!!
        }
                 
        if($algoCheck3 != $tc11){
            return false; //Geçersiz T.C. kimlik no!!!
        }
    }
              
        //GEÇERLİ T.C. Kimlik No.>";
        return true;
 }

//kisaltilmis (ev makarnasi :p)

function is_valid_tckn( $tckn )
{
    $x = $tckn;
    $valid1=((7*($x[0]+$x[2]+$x[4]+$x[6]+$x[8])-($x[1]+$x[3]+$x[5]+$x[7]))%10)==$x[9];
    $valid2=(($x[0]+$x[1]+$x[2]+$x[3]+$x[4]+$x[5]+$x[6]+$x[7]+$x[8]+$x[9])%10)==$x[10];
    return $valid1 && $valid2;
}

Delphi

Function TCKimlikDogrula(TCNo : String) : Boolean;
var
 bir,iki,uc,dort,bes,alti,yedi,sekiz,dokuz,onn,onbir,
 ilk,son,onuncu,onbirinci :  integer;
 _Soniki, pSoniki : string;
begin
 if (Length(TCNo) < 11) or (Length(TCNo) > 11 ) then
  begin
     ShowMessage('doğru düzgün gir tc no nu !!');
     Abort
  end
   else
 bir := StrToInt(TCNo[1]);
 iki := StrToInt(TCNo[2]);
 uc  := StrToInt(TCNo[3]);
 dort:= StrToInt(TCNo[4]);
 bes := StrToInt(TCNo[5]);
 alti:= StrToInt(TCNo[6]);
 yedi:= StrToInt(TCNo[7]);
 sekiz:= StrToInt(TCNo[8]);
 dokuz:= StrToInt(TCNo[9]);
 onn  := StrToInt(TCNo[10]);
 onbir:= StrToInt(TCNo[11]);
 
 ilk := (bir+uc+bes+yedi+dokuz) * 7;
 son := iki+dort+alti+sekiz;
 onuncu := (ilk - son) mod 10;
 onbirinci := (bir+uc+bes+yedi+dokuz+iki+dort+alti+sekiz+onuncu);
 onbirinci := onbirinci mod 10;
 
 _Soniki := IntToStr(onuncu) + IntToStr(onbirinci);
 pSoniki := TCNo[10] + TCNo[11];
 
 if _Soniki = pSoniki then
  begin
   Result := True;
  end
   else
    Result := False;
end;

Python

# -------------------------------------------------------------------------
# tc numarasının checksum kısmını hesaplayan kısım
def tcno_checksum(tcno):
    tc    = '%d' % tcno
    tc10  = int(tc[0]) + int(tc[2]) + int(tc[4]) + int(tc[6]) + int(tc[8])
    tc10 *= 7
    tc10 -= int(tc[1]) + int(tc[3]) + int(tc[5]) + int(tc[7])
    tc10 %= 10
 
    tc11  = int(tc[0]) + int(tc[1]) + int(tc[2]) + int(tc[3]) + int(tc[4])
    tc11 += int(tc[5]) + int(tc[6]) + int(tc[7]) + int(tc[8]) + int(tc10)
    tc11 %= 10
 
    return '%s%d%d' % (tc, tc10, tc11)

Tsql

CREATE PROCEDURE [dbo].[tckimliknoDogrulama]

(

@TCKimlikNo nvarchar(11)

)

AS

SET NOCOUNT ON

if @TCKimlikNo is null

begin

return 'false'

end

if LEN(@TCKimlikNo) <> 11

begin

return 'false'

end

--Sayi mi degil mi kontrolu

declare @count int

select @count=1

while @count<=LEN(@TCKimlikNo)

begin

if substring(@TCKimlikNo,@count,1)<>'0' and substring(@TCKimlikNo,@count,1)<>'1' and substring(@TCKimlikNo,@count,1)<>'2'

and substring(@TCKimlikNo,@count,1)<>'3' and substring(@TCKimlikNo,@count,1)<>'4' and substring(@TCKimlikNo,@count,1)<>'5'

and substring(@TCKimlikNo,@count,1)<>'6' and substring(@TCKimlikNo,@count,1)<>'7' and substring(@TCKimlikNo,@count,1)<>'8'

and substring(@TCKimlikNo,@count,1)<>'9'

begin

return 'false'

end

select @count= @count+1

end

--Cift mi degil mi kontrolu

if (substring(@TCKimlikNo,LEN(@TCKimlikNo),1)<>'0' and

substring(@TCKimlikNo,LEN(@TCKimlikNo),1)<>'2' and

substring(@TCKimlikNo,LEN(@TCKimlikNo),1)<>'4' and

substring(@TCKimlikNo,LEN(@TCKimlikNo),1)<>'6' and

substring(@TCKimlikNo,LEN(@TCKimlikNo),1)<>'8' )

begin

return 'false'

end

declare @tmp1 bigint,@tmp bigint,@asb nvarchar(9),@str nvarchar(5)

select @tmp1= convert(bigint,@tckimlikno)/100, @tmp= convert(bigint,@tckimlikno)/100

select @count =9,@asb=''

while @count>0

begin

select @str=substring(@TCKimlikNo,@count,1)

select @asb=@asb+@str

select @count = @count -1

end

declare @oddsum bigint,@evensum bigint,@evensumtot bigint,@oddsumtot bigint,@total bigint,@chkdigit1 bigint,@chkdigit2 bigint

SELECT @oddsum=convert(bigint,(substring(@asb,1,1)))+convert(bigint,(substring(@asb,3,1)))+convert(bigint,(substring(@asb,5,1)))+convert(bigint,(substring(@asb,7,1)))+convert(bigint,(substring(@asb,9,1)))

SELECT @evensum=convert(bigint,(substring(@asb,2,1)))+convert(bigint,(substring(@asb,4,1)))+convert(bigint,(substring(@asb,6,1)))+convert(bigint,(substring(@asb,8,1)))

select @oddsumtot=@oddsum,@evensumtot=@evensum

select @total=@oddsum*3+@evensum

select @chkdigit1= (10-@total%10)%10

select @oddsum= @chkdigit1+@evensumtot

select @evensum= @oddsumtot

select @total = @oddsum*3+@evensum

select @chkdigit2=(10-@total%10)%10

select @tmp =@tmp*100+@chkdigit1*10+@chkdigit2

if @tmp <> convert(bigint,@tckimlikno)

begin

return 'false'

end

else

begin return 'true'

end

RETURN

 

6 comments

  1. Excel için aşağıdaki kod kullanılabilir

    Function TCKN(x As String)
    Dim buff() As String
    Dim tekToplam, ciftToplam, uzunluk, toplamlar, onuncuRakam, onbirinciRakam As Integer

    buff = Split(StrConv(x, vbUnicode), Chr$(0))
    ReDim Preserve buff(UBound(buff) – 1)
    uzunluk = Application.CountA(buff)
    If Len(x) 11 Then
    TCKN = “Hatalı TCKN (11/” & uzunluk & “)!”
    ElseIf buff(uzunluk – 1) Mod 2 0 Then
    TCKN = “Hatalı TCKN (11.2)!”
    ElseIf buff(0) = 0 Then
    TCKN = “Hatalı TCKN (0)!”
    Else
    For i = 0 To uzunluk – 1
    If i Mod 2 0 And i > 0 And i < 9 Then
    ciftToplam = ciftToplam + buff(i)
    ElseIf i < 9 Then
    tekToplam = tekToplam + buff(i)
    End If
    If i < uzunluk – 1 Then
    toplamlar = toplamlar + buff(i)
    End If
    Next i

    onuncuRakam = ((tekToplam * 7) – ciftToplam) Mod 10
    onbirinciRakam = (toplamlar Mod 10)

    If onuncuRakam buff(uzunluk – 2) Then
    TCKN = “Hatalı TCKN (10)”
    ElseIf onbirinciRakam buff(uzunluk – 1) Then
    TCKN = “Hatalı TCKN (11)!”
    Else
    TCKN = “”
    End If
    End If
    End Function

  2. 1 , 2 , 3 , 4 LE BAŞLAYAN FARKLI FARKLI KİMLİK NO LARI VAR ACABA BUNLAR NEYE GÖRE BELİRLENİYOR IRK OLARAK SOY AGACI OLARAK BİR FİŞLEME OLMA İHTİMALİ VAR MI BİLGİNİZ VARSA PAYLAŞIRSANIZ SEVİNİRİM.

    1. yok bu baslangic taki sayinin aile kutuk numarasi ile ilgisi var. Yabanci vatandaslarin 99 ile basladiginida belirtiyim. (bir yunan vatandasi olarak anneminde bu sekilde) orada ilk 4 hanelik kesiti disardan gelmis olan ulkeye gore belirleyeceklerdi sonradan basvuru sirasina gore duzenlemisler.
      Algoritmada akraba olma algoritmasi da mevcut, tamda bu gun bir arkadastan bunun ile ilgili bilgi almistim. Python’da akrabalik kontrol fonksiyonu asagidaki gibidir.


      def akraba_tcno(tcno, adet):
      akraba_liste = ''
      tc = int(tcno[0:-2])
      t = tc - 29999 * (1 %2B int(adet / 2))
      for i in range(adet%2B1):
      t %2B= 29999
      atc = tcno_checksum(t)
      if atc == tcno:
      pass
      else:
      akraba_liste %2B= "'%s'," % atc
      return akraba_liste[0:-1]

  3. bilgi için teşekkürler

    function tckimlik(kno) {
    var desen = /^[0-9]{11,11}/;
    if ((kno).match(desen)) {

    if (Number(kno.charAt(0)) == 0) {

    return false;
    }

    var tekler = Number(kno.charAt(0)) + Number(kno.charAt(2)) + Number(kno.charAt(4)) + Number(kno.charAt(6)) + Number(kno.charAt(8));
    var ciftler = Number(kno.charAt(1)) + Number(kno.charAt(3)) + Number(kno.charAt(5)) + Number(kno.charAt(7));
    var basamak10 = (tekler * 7 – ciftler) % 10;
    var toplam = (tekler + ciftler + Number(kno.charAt(9))) % 10;

    if (basamak10 != Number(kno.charAt(9))) {

    return false;
    }
    if (toplam != Number(kno.charAt(10))) {

    return false;
    } else return true;

    } else return false;

    }

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir

This site uses Akismet to reduce spam. Learn how your comment data is processed.