Formül
Haneler soldan sağa d1, d2, … d11 diye adlandırılırsa:
- d1 ≠ 0: numara 0 ile başlamaz ve tam 11 rakamdır.
- d10 = ((d1 + d3 + d5 + d7 + d9) × 7 − (d2 + d4 + d6 + d8)) mod 10
- d11 = (d1 + d2 + … + d10) mod 10
"mod 10", 10'a bölümden kalan, yani sonucun birler basamağıdır. Örnekte 123456789 için tek sıradaki hanelerin toplamı 25, çift sıradakilerin toplamı 20; (25 × 7 − 20) = 155 olduğundan 10. hane 5, ilk 10 hanenin toplamı 50 olduğundan 11. hane 0 olur: 12345678950.
Negatif ara sonuç
Çift sıradaki haneler büyükse fark negatife düşebilir. Örneğin 190909090 için (1 × 7 − 36) = −29 olur. Matematikteki mod işleminde sonuç her zaman 0 ile 9 arasındadır: −29 sayısından küçük ya da ona eşit en büyük 10 katı −30 olduğundan kalan 1 çıkar. Birçok programlama dilinde % işleci negatif sonuç verir: JavaScript, PHP, C#, Java ve SQLite gibi dillerde -29 % 10 ifadesinin sonucu −9 çıkar; bu yüzden kodda ((x % 10) + 10) % 10 biçimi kullanılır. Python'da ve Excel'in MOD işlevinde sonuç zaten pozitiftir.
Bu kural neyi yakalar?
Tek bir hanenin yanlış yazılması her zaman yakalanır: hangi hane değişirse değişsin ilk 10 hanenin toplamı değişir ve 11. hane tutmaz. Yan yana iki hanenin yer değiştirmesinin bir kısmı ise yakalanmayabilir; kontrol haneleri yazım hatasına karşı bir süzgeçtir, kimlik doğrulaması değildir.
Kod örnekleri
Her işlev 11 karakterlik bir metin alır ve numara algoritmaya uyuyorsa true döndürür. Numarayı sayı (integer) olarak değil metin olarak tutun; böylece uzunluk ve baştaki 0 denetimi doğru çalışır.
JavaScript
function tcKimlikGecerliMi(tc) {
if (!/^[1-9][0-9]{10}$/.test(tc)) return false;
const d = [...tc].map(Number);
const tek = d[0] + d[2] + d[4] + d[6] + d[8];
const cift = d[1] + d[3] + d[5] + d[7];
const hane10 = (((tek * 7 - cift) % 10) + 10) % 10;
const hane11 = d.slice(0, 10).reduce((a, b) => a + b, 0) % 10;
return d[9] === hane10 && d[10] === hane11;
} TypeScript
export function tcKimlikGecerliMi(tc: string): boolean {
if (!/^[1-9][0-9]{10}$/.test(tc)) return false;
const d: number[] = [...tc].map(Number);
const tek = d[0] + d[2] + d[4] + d[6] + d[8];
const cift = d[1] + d[3] + d[5] + d[7];
const hane10 = (((tek * 7 - cift) % 10) + 10) % 10;
const hane11 = d.slice(0, 10).reduce((a, b) => a + b, 0) % 10;
return d[9] === hane10 && d[10] === hane11;
} Python
def tc_kimlik_gecerli_mi(tc: str) -> bool:
if len(tc) != 11 or not (tc.isascii() and tc.isdigit()) or tc[0] == "0":
return False
d = [int(c) for c in tc]
tek = d[0] + d[2] + d[4] + d[6] + d[8]
cift = d[1] + d[3] + d[5] + d[7]
return d[9] == (tek * 7 - cift) % 10 and d[10] == sum(d[:10]) % 10 PHP
function tcKimlikGecerliMi(string $tc): bool
{
if (!preg_match('/^[1-9][0-9]{10}$/D', $tc)) {
return false;
}
$d = array_map('intval', str_split($tc));
$tek = $d[0] + $d[2] + $d[4] + $d[6] + $d[8];
$cift = $d[1] + $d[3] + $d[5] + $d[7];
$hane10 = (($tek * 7 - $cift) % 10 + 10) % 10;
$hane11 = array_sum(array_slice($d, 0, 10)) % 10;
return $d[9] === $hane10 && $d[10] === $hane11;
} SQL (SQLite)
-- SQLite: kisiler tablosundaki tckn sütunu (TEXT) için geçerlilik
WITH h AS (
SELECT tckn,
CAST(substr(tckn, 1, 1) AS INTEGER) AS d1, CAST(substr(tckn, 2, 1) AS INTEGER) AS d2,
CAST(substr(tckn, 3, 1) AS INTEGER) AS d3, CAST(substr(tckn, 4, 1) AS INTEGER) AS d4,
CAST(substr(tckn, 5, 1) AS INTEGER) AS d5, CAST(substr(tckn, 6, 1) AS INTEGER) AS d6,
CAST(substr(tckn, 7, 1) AS INTEGER) AS d7, CAST(substr(tckn, 8, 1) AS INTEGER) AS d8,
CAST(substr(tckn, 9, 1) AS INTEGER) AS d9, CAST(substr(tckn, 10, 1) AS INTEGER) AS d10,
CAST(substr(tckn, 11, 1) AS INTEGER) AS d11
FROM kisiler
)
SELECT tckn,
length(tckn) = 11
AND tckn NOT GLOB '*[^0-9]*'
AND d1 <> 0
AND d10 = (((d1 + d3 + d5 + d7 + d9) * 7 - (d2 + d4 + d6 + d8)) % 10 + 10) % 10
AND d11 = (d1 + d2 + d3 + d4 + d5 + d6 + d7 + d8 + d9 + d10) % 10 AS gecerli
FROM h; Excel formülü
Numara A2 hücresindeyse aşağıdaki formül DOĞRU ya da YANLIŞ döndürür. Hücre metin ya da sayı biçiminde olabilir. Formülü aşağı doğru kopyalayarak bütün sütunu denetleyebilirsiniz.
Türkçe Excel
=EĞERHATA(VE(UZUNLUK(A2)=11;SOLDAN(A2;1)<>"0";MOD((PARÇAAL(A2;1;1)+PARÇAAL(A2;3;1)+PARÇAAL(A2;5;1)+PARÇAAL(A2;7;1)+PARÇAAL(A2;9;1))*7-(PARÇAAL(A2;2;1)+PARÇAAL(A2;4;1)+PARÇAAL(A2;6;1)+PARÇAAL(A2;8;1));10)=PARÇAAL(A2;10;1)*1;MOD(PARÇAAL(A2;1;1)+PARÇAAL(A2;2;1)+PARÇAAL(A2;3;1)+PARÇAAL(A2;4;1)+PARÇAAL(A2;5;1)+PARÇAAL(A2;6;1)+PARÇAAL(A2;7;1)+PARÇAAL(A2;8;1)+PARÇAAL(A2;9;1)+PARÇAAL(A2;10;1);10)=PARÇAAL(A2;11;1)*1);YANLIŞ) İngilizce Excel
=IFERROR(AND(LEN(A2)=11,LEFT(A2,1)<>"0",MOD((MID(A2,1,1)+MID(A2,3,1)+MID(A2,5,1)+MID(A2,7,1)+MID(A2,9,1))*7-(MID(A2,2,1)+MID(A2,4,1)+MID(A2,6,1)+MID(A2,8,1)),10)=MID(A2,10,1)*1,MOD(MID(A2,1,1)+MID(A2,2,1)+MID(A2,3,1)+MID(A2,4,1)+MID(A2,5,1)+MID(A2,6,1)+MID(A2,7,1)+MID(A2,8,1)+MID(A2,9,1)+MID(A2,10,1),10)=MID(A2,11,1)*1),FALSE) Bir numarayı elle denemek için TC kimlik no doğrulama, test verisi için TC no üret aracını kullanabilirsiniz.