Temat (nie)unikatowych numerów kont pojawił się w tej dyskusji nt. tokenów (dead link, domena przejęta), a szerzej opisany jest w tym wpisie, ile cyfr potrzeba, by numer rachunku bankowego był unikatowy. Przyznam, że nie miałem zielonego pojęcia nt. algorytmu weryfikacji numeru IBAN, ale na chłopski rozum kolizje zdarzą się wszędzie. Stwierdziłem, że najlepsza metoda nauki to napisać skrypt do sprawdzania. Oczywiście w Perlu. Przy okazji wyszło mi, że Perl średnio sobie radzi z dużymi liczbami, a Python dobrze, ale dzięki temu znalazłem pięknego gotowca w postaci modułu do sprawdzania poprawności numeru IBAN.
Pierwsze, co rzuca się w oczy, to fakt, że tak naprawdę numer IBAN jest zamieniany na liczbę, a czy jest poprawny określane jest tylko na podstawie jednego testu – jeśli reszta z dzielenia tej dużej cyfry przez 97 wynosi 1, to numer jest poprawny.
Chwila zabawy programem i okazuje się, że dla 3 brakujących cyfr w dowolnym miejscu rachunku można wygenerować ok. 10 kolizji. Pewnie ma to coś wspólnego z faktem, że 97 jest liczbą pierwszą, a samo 97 mieści się w każdym tysiącu właśnie 10-11 razy, ale tutaj już by się matematyk przydał i zasady podzielności przez 97 (hasło do Google cechy podzielności przez 97 nic sensownego nie znalazło niestety).
Inna szansa, że nasze PL na początku numeru (które wraz z następującymi po nim dwiema cyframi jest przesuwane na koniec i zamieniane na liczby patrz algorytm weryfikacji numeru IBAN) jest na tyle pechowe, że powoduje taką przykrą przypadłość. Ale to łatwo sprawdzić – dzięki użyciu ogólnej biblioteki skrypcik do bruteforce’owania numerów IBAN powinien działać dla wszystkich krajów.
Póki co konkluzja jest taka, że aby numer był unikatowy, to trzeba podać wszystkie cyfry. Przy dobrym wietrze może się zdarzyć, że 1 można opuścić.
PS. Nie cierpię słowa unikalny. Dla mnie oznacza ono możliwy do uniknięcia. Zamiast niego możnaby używać słowa unikatowy. Niestety SJP traktuje je jako synonimy.
Tego jednak raczej nie można tak prosto analizować – przestrzeń numerów jest dalece nieciągła (masz 2 cyfry kontrolne, 8 cyfr numeru banku, potem numer wewnątrzbankowy który najczęściej ma jakąś wewnętrzną ustaloną strukturę). Czasem goły sufiks odpowiedniej długości czy infix odkądś dokądś jest de facto id rachunku.
Inna sprawa, że była kiedyś afera gdy babka rąbnęła się w dwóch cyfrach tak niefartownie, że suma kontrolna się spełniła – i spłacała cudzy kredyt. Któreś pko to było ale nie pamięam czy bp czy sa.
@Mekkkk: Być może masz rację, ale jeśli ktoś będzie chciał podszywać się pod inne konta, to swoje konta też założy w bankach. Czyli 2 cyfry kontrolne, 8 cyfr numeru banku, numer wewnątrzbankowy się zgadzają z automatu. Pozostaje im tylko dopasowanie tego, co się wyświetliło klientowi w SMS ze swoim, istniejącym już numerem konta.
Osobnym zagadnieniem jest pytanie, ile rachunków w danym banku trzeba by założyć, by mieć prawdopodobieństwo na zadanym poziomie, że będzie kolizja dowolnym numerem konta z tego banku, przy zmiennych (tj. nie podanych w SMS) n cyfrach (hmm, może ja to policzę kiedyś?).
Chyba, że banki nie podadzą fragmentu identyfikującego bank w SMS, wtedy może trafić do innego banku, ale to jest dla przestępcy nieistotne. Istotne jest, czy posiada konto z kolizją dla danej operacji – więc sam algorytm operacyjny jest dla nich: sprawdź, czy cyfry numeru konta, które dostał klient w SMSie pasują do któregoś z kontrolowanych rachunków, jeśli tak, to podmień, jeśli nie – pozwól wykonać operację na oryginalne konto.
Obawiam się, że to zdecydowany overkill. Gros ludzi pewnie w ogóle na ten numerek nie będzie spoglądać, może poza kilkoma pierwszymi przelewami, a jeśli nawet spojrzą, to porównają z tekstem aktualnie wyświetlanym na ekranie…