Мой вариант:
function getIsikukoodControllNumber( $isikukood ) { $isikukood = (string) $isikukood; // Эту строку можно опустить, т.к. PHP сам приведёт тип к стрингу // $k - начало ряда // цикл делает максимум 2 итерации for ( $k = 1; $k <= 3; $k += 2 ) { $j = $k; $s = 0; // сумма // $i - порядковый номер цифры в исикукоде for ( $i = 0; $i < 10; ++$i ) { $s += $j * $isikukood{$i}; $j = ( 9 == $j ? 1 : $j + 1 ); } if ( ( $s %= 11 ) < 10 ) { return $s; } } return 0; }
Спецификация из вики:
Kontrollnumber arvutatakse järgnevalt:
1) isikukoodi numbritele esimene kuni eelviimane (s.t. välja arvatud kontrolljärgu koht) seatakse vasakult paremale kaalud 1, 2, 3, 4, 5, 6, 7, 8, 9, 1;
2) numbrid korrutatakse kaaludega ja saadud tulemused liidetakse kokku;
3) leitakse saadud summale (2) jääk 11-ga jagamisel;
4) kui tulemus (3) on alla 10, siis on see kontrollnumbriks;
5) kui tulemus (3) on võrdne 10, siis asendatakse kaalud 3, 4, 5, 6, 7, 8, 9, 1, 2, 3 ning korratakse arvutust;
6) kui tulemus (5) on alla 10, siis on see kontrollnumbriks;
7) kui tulemus (5) on võrdne 10, siis kontrollnumbriks on 0.
Пример кода из википедии
<?php $isikukood = '3760503029'; function isikukoodi_kontrollsumma($isikukood) { for($j = 1; $j <= 9; $j++) $summa += $j * $isikukood[$j-1]; $summa += $isikukood[9]; $summa %= 11; if($summa < 10 && $isikukood[10] == $summa) return $summa; if($summa == 10) { $summa = 0; for($j = 3, $i = 0; $j <= 9; $j++, $i++) $summa += $j * $isikukood[$i]; for($j = 1; $j <= 3; $j++, $i++) $summa += $j * $isikukood[$i]; $summa %= 11; if($summa < 10 && $isikukood[10] == $summa) return $summa; if($summa == 10) return 0; } return $summa; } echo isikukoodi_kontrollsumma($isikukood); ?>
Зачем тут эта проверка (2е выражение), по-моему это отклонение от спецификации.if($summa < 10 && $isikukood[10] == $summa) return $summa;
Может будут более изящные примеры на других языках?
Сообщение изменено: Setor (27 мая 2009 - 19:16 )