Алгоритъм за проверка на Единен идентификационен код (ЕИК) на фирма – БУЛСТАТ

Ако се чудите как да валидирате ЕИК на фирма и по какъв алгоритъм се генерира ЕИК, добре е да  прочете подробности тук.

С думи кратки, ЕИК е уникален код на дадена фирма, нещо като нейно ЕГН. ЕИК може да бъде 9 или 13 цифри. По принцип е само 9, но когато фирмата има клонове, се ползват още 4 цифри.

Алгоритъмът, по който се генерира ЕИК е лесен за имплементация. Основната идея при 9-цифровия ЕИК е, че последната 9-та цифра е контролна сума. Изчислява се на база предходните 8 цифри и служи за проверка. Аналогичен е случаят с 13-цифров ЕИК, където освен 9-тата цифра се използва и 13-тата цифра за проверка(контролна сума). Ако не ви се занимава да реализирате алгоритъма, може да погледнете моята имплементация:

package eik.test;

public class EIKValidator {
 private static int[] FIRST_SUM_9DIGIT_WEIGHTS = { 1, 2, 3, 4, 5, 6, 7, 8 };
 private static int[] SECOND_SUM_9DIGIT_WEIGHTS = { 3, 4, 5, 6, 7, 8, 9, 10 };
 private static int[] FIRST_SUM_13DIGIT_WEIGHTS = { 2, 7, 3, 5 };
 private static int[] SECOND_SUM_13DIGIT_WEIGHTS = { 4, 9, 5, 7 };

 public static boolean calculateChecksumForNineDigitsEIK(String eik) {
   int[] digits = checkInput(eik, 9);
   int ninthDigit = calculateNinthDigitInEIK(digits);
   return ninthDigit == digits[8];
 }

 public static boolean calculateChecksumForThirteenDigitsEIK(String eik) {
   int[] digits = checkInput(eik, 13);
   int thirteenDigit = calculateThirteenthDigitInEIK(digits);
   return thirteenDigit == digits[12];
 }

 private static int calculateNinthDigitInEIK(int[] digits) {
   int sum = 0;
   for (int i = 0; i < 8; i++) {
     sum = sum + (digits[i] * FIRST_SUM_9DIGIT_WEIGHTS[i]);
   }
   int remainder = sum % 11;
   if (remainder != 10) {
     return remainder;
   }
   // remainder= 10
   int secondSum = 0;
   for (int i = 0; i < 8; i++) {
     secondSum = secondSum + (digits[i] * SECOND_SUM_9DIGIT_WEIGHTS[i]);
   }
   int secondRem = secondSum % 11;
   if (secondRem != 10) {
     return secondRem;
   }
   // secondRemainder= 10
   return 0;
 }

 private static int calculateThirteenthDigitInEIK(int[] digits) {
   int ninthDigit = calculateNinthDigitInEIK(digits);
   if (ninthDigit != digits[8]) {
     throw new IllegalArgumentException("Incorrect 9th digit in EIK-13.");
   }
   // 9thDigit is a correct checkSum. Continue with 13thDigit
   int sum = 0;
   for (int i = 8, j = 0; j < 4; i++, j++) {
     sum = sum + (digits[i] * FIRST_SUM_13DIGIT_WEIGHTS[j]);
   }
   int remainder = sum % 11;
   if (remainder != 10) {
     return remainder;
   }
   // remainder= 10
   int secondSum = 0;
   for (int i = 8, j = 0; j < 4; i++, j++) {
     secondSum = secondSum + (digits[i] * SECOND_SUM_13DIGIT_WEIGHTS[j]);
   }
   int secondRem = secondSum % 11;
   if (secondRem != 10) {
     return secondRem;
   }
   // secondRemainder= 10
   return 0;
 }

 private static int[] checkInput(String eik, int eikLength) {
   if (eik != null && eik.length() != eikLength) {
     throw new IllegalArgumentException("Incorrect count of digits in EIK: "
       + eik.length() + "!= 9 or 13");
   }
   // eik.length= eikLength
   char[] charDigits = eik.toCharArray();
   int[] digits = new int[charDigits.length];
   for (int i = 0; i < digits.length; i++) {
     if (Character.isDigit(charDigits[i])) {
       digits[i] = Character.digit(charDigits[i], 10);
     } else {
       throw new IllegalArgumentException(
         "Incorrect input character. Only digits are allowed.");
     }
   }
   return digits;
 }
}

Направих 10 успешни JUnit теста само за 9-цифровия ЕИК. Ако се чудите откъде може да вземете реални ЕИК, може да посетите Търговския регистър в сайта на Агенцията по вписванията. Или пък този сайт. За съжаление не успях да намеря в интернет 13-цифров ЕИК. Така, че алгорътимът за 13-цифров ЕИК не е тестван.

Ако откриете някаква грешка, неточност, подобрение, ще се радвам да споделите. Надявам се, че съм помогнал на “приятел в нужда”( се познава). :)

Advertisements

About tsvetanv

Friends, Books, Music, Math, Programming.
This entry was posted in Java and tagged , , . Bookmark the permalink.

5 Responses to Алгоритъм за проверка на Единен идентификационен код (ЕИК) на фирма – БУЛСТАТ

  1. Darin says:

    Blagodaria za bulstata, to4no tova mi triabva6e!

  2. theGoldenFish says:

    Благодаря за споделените знания. Въпреки, че нищо не разбирам от Java този код ми помогна да създам своя собствена функция за проверка на ЕИК използвайки PHP.

    Ако искате да тествате алгоритъмът за 13-цифров ЕИК потърсете в търговският регистър – Амарант България ООД. Дружеството има достатъчно клонове, включително и такъв с остатък 10. При мен скрипта работи перфектно, но е на PHP.
    Сигурна съм, че и Вашият алгоритъм работи без грешка :)

  3. Lubo says:

    Здравей,
    Знаеш ли как седят нещата с компании които са от ЕС. Техните номера по същия начин ли се генерират?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s