Księga liczb: walidacja NIPu i REGONu

Po ukończeniu warstwy dostępu do danych, mogę zabrać się za logikę biznesową. Na początek – walidacja numerów NIP i REGON.
Czym jest NIP, wie mniej więcej każdy. Czym jest REGON, zapewne bardziej “mniej” niż “więcej”. Z kolei wiedzę o tym, co oznaczają poszczególne cyfry tych numerów, moża śmiało uznać za tajemną. Dziś, na potrzeby projektu, uchylę rąbka tajemnicy: zajmę się ich ostatnimi cyframi. Są to cyfry kontrolne, wyznaczane algorytmicznie. Aby je wyliczyć, należy:

 1. pomnożyć każdą z poprzednich cyfr przez odpowiednie wagi,
2. zsumować wyniki mnożeń,
3. obliczyć resztę z dzielenia przez 11.

NIP
Przyjrzyjmy się bliżej numerowi NIP. Aby określić, czy ciąg znaków jest poprawnym Numerem Identyfikacji Podatkowej, należy przede wszystkim sprawdzić, czy w ogóle jest numerem (linia nr 5 kodu, który zaraz przedstawię). Konkretniej: numerem dziesięciocyfrowym (linia nr 7). Dopiero teraz można zastosować wyżej przedstawiony algorytm – wspomniane w punkcie pierwszym wagi to kolejno: 6, 5, 7, 2, 3, 4, 5, 6, 7. Programistom wygodniej będzie spojrzeć na kod:

public static bool ValidateNip(string nipString)
{
	long nip;

	if (long.TryParse(nipString, out nip))
	{
		int[] digitArray = nip.ToDigitArray();

		if (digitArray.Length == 10)
		{
			int sum = digitArray[0] * 6
					+ digitArray[1] * 5
					+ digitArray[2] * 7
					+ digitArray[3] * 2
					+ digitArray[4] * 3
					+ digitArray[5] * 4
					+ digitArray[6] * 5
					+ digitArray[7] * 6
					+ digitArray[8] * 7;

			if (sum % 11 == digitArray[9])
				return true;
		}
	}

	return false;
}

W podświetlonej (zaciemnionej?) linii używam extension method zamieniającej liczbę na wektor jej cyfr:

private static int[] ToDigitArray(this long number)
{
	// przykładowo zamienia 123456 na { 1, 2, 3, 4, 5, 6 }
	// (najbardziej znacząca cyfra -> indeks 0)

	string str = number.ToString();
	int[] digitArray = new int[str.Length];

	for (int i = 0; i != digitArray.Length; i++)
		digitArray[i] = int.Parse(str[i].ToString());

	return digitArray;
}

REGON
Numer Rejestru Gospodarki Narodowej może składać się z dziewięciu lub czternastu cyfr. Wagi, o których mowa w algorytmie wyznaczania cyfry kontrolnej, wynoszą odpowiednio:
1. 8, 9, 2, 3, 4, 5, 6, 7 dla REGONu 9-cyfrowego,
2. 2, 4, 8, 5, 0, 9, 7, 3, 6, 1, 2, 4, 8 dla REGONu – 14-cyfrowego.
Cały proces sprawdzania popraności tego numeru wygląda więc tak:

public static bool ValidateRegon(string regonString)
{
	long regon;

	if (long.TryParse(regonString, out regon))
	{
		int[] digitArray = regon.ToDigitArray();

		if (digitArray.Length == 9)
		{
			int sum = digitArray[0] * 8
					+ digitArray[1] * 9
					+ digitArray[2] * 2
					+ digitArray[3] * 3
					+ digitArray[4] * 4
					+ digitArray[5] * 5
					+ digitArray[6] * 6
					+ digitArray[7] * 7;

			int mod = sum % 11;

			if (mod == 10)
				mod = 0;

			if (mod == digitArray[8])
				return true;
		}
		else if (digitArray.Length == 14)
		{
			int sum = digitArray[0] * 2
					+ digitArray[1] * 4
					+ digitArray[2] * 8
					+ digitArray[3] * 5
					+ digitArray[4] * 0
					+ digitArray[5] * 9
					+ digitArray[6] * 7
					+ digitArray[7] * 3
					+ digitArray[8] * 6
					+ digitArray[9] * 1
					+ digitArray[10] * 2
					+ digitArray[11] * 4
					+ digitArray[12] * 8;

			int mod = sum % 11;

			if (mod == 10)
				mod = 0;

			if (mod == digitArray[13])
				return true;
		}
	}

	return false;
}

Jak widać, pierwsze kroki po warstwie logiki biznesowej to raczej spacer, niż bieg przez płotki. Na horyzoncie majaczą się jednak takie problemy, jak zamiana liczb na słowa, czy obsługa szablonów numerów faktur – o tym w przyszłych wpisach, zapraszam!

2 thoughts on “Księga liczb: walidacja NIPu i REGONu”

  1. Jak to mówią , dokładnie cegiełki pod dobre fundamenty to prosta sprawa :) Dobrze , że łatwe na początku rzeczy wybierasz – bo czasem człowiek się zawiesza na czymś bardziej skomplikowanym ( powoduje to brak chęci do pracy na projektem )

  2. To prawda :). Zdarza się też, że człowiek najpierw zaimplmentuje skomplikowane funkcjonalności, a potem na rzeczy proste trudno mu znaleźć chęci – bo wydają się zbyt proste.

Comments are closed.