Przejdź do treści
Pewniak INF.04Trudny

Walidacja danych wejściowych i cyfra kontrolna

Walidator numeru PESEL z arkusza INF.04 to wzorzec, który wraca w wielu odsłonach. Jak liczyć cyfrę kontrolną i jak przyjmować dane, żeby program nie wywalał się na pustym polu.

Arkusz INF.04 ze stycznia 2024 kazał napisać konsolowy walidator numeru PESEL wraz z cyfrą kontrolną. Ten sam mechanizm pojawia się pod innymi nazwami: numer konta, kod produktu, numer faktury. Zasada jest zawsze taka sama i warto ją rozumieć, a nie zapamiętywać.

1. Jak działa cyfra kontrolna

Każdej cyfrze numeru przypisuje się wagę, mnoży, sumuje, a z sumy wylicza cyfrę dopełniającą. Dla numeru PESEL wagi to 1, 3, 7, 9 i tak w kółko dla pierwszych dziesięciu cyfr:

static bool CzyPoprawnyPesel(string pesel)
{
  if (pesel == null || pesel.Length != 11)
      return false;

  foreach (char z in pesel)
      if (!char.IsDigit(z)) return false;

  int[] wagi = { 1, 3, 7, 9, 1, 3, 7, 9, 1, 3 };
  int suma = 0;

  for (int i = 0; i < 10; i++)
      suma += wagi[i] * (pesel[i] - '0');

  int kontrolna = (10 - (suma % 10)) % 10;

  return kontrolna == (pesel[10] - '0');
}

Zewnętrzne % 10 w wyliczeniu cyfry kontrolnej nie jest ozdobnikiem. Gdy suma dzieli się przez 10 bez reszty, bez niego wyszłoby 10 zamiast 0 — i wszystkie takie numery program uznałby za błędne.

2. Kolejność sprawdzeń ma znaczenie

  • Najpierw sprawdź, czy dane w ogóle istniejąnull albo pusty tekst.
  • Potem długość. Odwołanie do jedenastego znaku w krótszym tekście kończy się wyjątkiem.
  • Potem, czy to same cyfry. Bez tego odejmowanie znaku zera da bezsensowny wynik.
  • Na końcu licz cyfrę kontrolną. Dopiero teraz masz pewność, że dane nadają się do obliczeń.

Odwrócenie tej kolejności to najczęstsza przyczyna wywalenia się programu podczas sprawdzania. Egzaminator wpisze pustą wartość albo trzy znaki i zobaczy komunikat o błędzie zamiast działającej walidacji.

3. Bezpieczne wczytywanie z konsoli

Console.Write("Podaj liczbę: ");

if (int.TryParse(Console.ReadLine(), out int liczba))
  Console.WriteLine($"Podano: {liczba}");
else
  Console.WriteLine("To nie jest poprawna liczba.");

TryParse zamiast Parse to jeden z tych drobiazgów, które odróżniają program zaliczony od programu, który przerywa działanie na pierwszej literze wpisanej przez użytkownika. Więcej w teorii INF.04.

Kolejne zagadnienie, które warto mieć opanowane:

Testy jednostkowe metody