Jak wygenerować kod/numer weryfikacyjny?

Pracuję nad aplikacją, w której użytkownicy muszą wykonać połączenie i wpisać numer weryfikacyjny za pomocą klawiatury swojego telefonu.

Chciałbym być w stanie wykryć, czy liczba, którą wpisują jest poprawna, czy nie. System telefoniczny nie ma dostępu do listy ważnych numerów, ale zamiast tego zweryfikuje numer w oparciu o algorytm (np. numer karty kredytowej).

Oto niektóre z wymagań:

  • musi być trudno wpisać poprawny losowy Kod
  • To musi być trudne, aby mieć poprawny kod, jeśli zrobię literówkę (tranpozycja cyfr, zła cyfra)
  • muszę mieć uzasadnioną liczbę możliwych kombinacji (powiedzmy 1M)
  • kod musi być jak najkrótszy, aby uniknąć błędów ze strony Użytkownika

Biorąc pod uwagę te wymagania, jak można wygenerować taką liczbę ?

EDIT:

@ Haaked: kod musi być numeryczny, ponieważ użytkownik wpisuje go telefonem.

@matt b: na pierwszym krok, kod jest wyświetlany na stronie internetowej, drugim krokiem jest wywołanie i wpisanie kodu. Nie znam numeru telefonu użytkownika.

Folowup: znalazłem kilka algorytmów do sprawdzania ważności liczb(zobacz ten interesujący projekt kodu Google : checkDigits ).

Author: Tshepang, 2008-09-05

9 answers

Po kilku badaniach, myślę, że pójdę z ISO 7064 Mod 97,10 wzór. Wydaje się dość solidny, ponieważ jest używany do walidacji IBAN (Międzynarodowy Numer konta bankowego).

Wzór jest bardzo prosty:

  1. weź liczbę: 123456
  2. Zastosuj poniższy wzór, aby uzyskać sumę kontrolną 2 cyfr : mod(98 - mod(number * 100, 97), 97) => 76
  3. numer Konkat i suma kontrolna w celu uzyskania kodu = > 12345676
  4. aby zweryfikować kod, Sprawdź, czy mod(code, 97) == 1

Test :

  • mod(12345676, 97) = 1 = > Dobry
  • mod(21345676, 97) = 50 => BAD !
  • mod(12345678, 97) = 10 => BAD !

Najwyraźniej algorytm ten wychwytuje większość błędów.

Inną ciekawą opcją był algorytm Verhoeffa . Ma tylko jedną cyfrę weryfikacyjną i jest trudniejsza do wdrożenia (w porównaniu do prostego wzoru powyżej).
 29
Author: Costo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-23 17:37:43

Dla kombinacji 1M będziesz potrzebował 6 cyfr. Aby upewnić się, że nie ma żadnych przypadkowo ważnych kodów, proponuję 9 cyfr z szansą 1/1000, że losowy kod działa. Sugerowałbym również użycie innej cyfry (łącznie 10) do wykonania sprawdzenia integralności . Jeśli chodzi o wzorce dystrybucji, wystarczy losowa, a cyfra kontrolna zapewni, że pojedynczy błąd nie spowoduje poprawnego kodu.

Edit: najwyraźniej nie do końca przeczytałem Twoją prośbę. Korzystanie z karty kredytowej numer, możesz na nim wykonać hash (MD5 lub SHA1 lub coś podobnego). Następnie obcinasz w odpowiednim miejscu (na przykład 9 znaków) i konwertujesz do bazy 10. Następnie dodajesz cyfrę kontrolną i powinna ona działać mniej więcej dla Twoich celów.

 4
Author: Kyle Cronin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-05 17:17:31

Chcesz podzielić swój kod. Część powinna być 16-bitowym CRC reszty kodu.

Jeśli chcesz mieć tylko numer weryfikacyjny, po prostu użyj numeru sekwencyjnego (zakładając, że masz pojedynczy punkt generowania). W ten sposób wiesz, że nie dostaniesz duplikatów.

Następnie prefiks sekwencji z CRC-16 tego numeru sekwencji i jakiś klucz prywatny. Możesz użyć czegokolwiek do klucza prywatnego, o ile zachowasz jego prywatność. Zrób coś wielkiego, przynajmniej GUID , ale może to być tekst do Wojna i Pokój z Projektu Gutenberg . Po prostu musi być tajemnicą i stałą. Posiadanie klucza prywatnego uniemożliwia ludziom sfałszowanie klucza, ale użycie 16-bitowego CR ułatwia jego złamanie.

Aby potwierdzić, wystarczy podzielić numer na dwie części, a następnie wziąć CRC-16 numeru sekwencyjnego i klucz prywatny.

Jeśli chcesz bardziej zasłonić sekwencyjną część, podziel CRC na dwie części. Umieść 3 cyfry na z przodu i 2 z tyłu sekwencji (zero padu więc długość CRC jest spójna).

Ta metoda pozwala na rozpoczęcie od mniejszych klawiszy. Pierwsze 10 klawiszy będzie 6 cyfr.

 2
Author: Jim McKeeth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-05 18:34:17

Czy to muszą być tylko liczby? Możesz utworzyć losową liczbę od 1 do 1M (sugerowałbym jednak jeszcze wyższą), a następnie Base32 zakodować ją. Następną rzeczą, którą musisz zrobić ,to Hash tej wartości (używając tajnej wartości salt) i base32 zakodować hash. Następnie dołącz dwa ciągi razem, być może oddzielone myślnikiem.

W ten sposób możesz algorytmicznie zweryfikować kod przychodzący. Po prostu bierzesz lewą stronę kodu, mieszasz go używając swojej sekretnej soli i porównujesz to wartość po prawej stronie kodu.

 1
Author: Haacked,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-05 16:44:19
  • muszę mieć uzasadnioną liczbę możliwych kombinacji (powiedzmy 1M)
  • Kod musi być jak najkrótszy, aby uniknąć błędów ze strony użytkownika

Cóż, jeśli chcesz mieć co najmniej milion kombinacji, to potrzebujesz co najmniej sześciu cyfr. Czy to wystarczająco krótkie?

 0
Author: Chris Upchurch,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-05 16:33:28

Kiedy tworzysz kod weryfikacyjny, masz dostęp do numeru telefonu dzwoniącego?

Jeśli tak, użyłbym numeru telefonu rozmówcy i uruchomił go przez jakąś funkcję haszującą, abyś mógł zagwarantować, że kod weryfikacyjny, który podałeś rozmówcy w kroku 1, jest tym samym, który wprowadzają w Kroku 2 (aby upewnić się, że nie używają kodu weryfikacyjnego znajomego lub po prostu zgadli).

Co do hashowania, Nie wiem czy to możliwe, aby wziąć 10 cyfrowy numer i wyjdzie z wynikiem hash, który będzie

Oczywiście nie będzie to działać, jeśli numer telefonu użyty w kroku 1 jest inny niż ten, z którego dzwonią w Kroku 2.

 0
Author: matt b,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-05 16:42:33

Zakładając, że już wiesz, jak wykryć klucz, który użytkownik uderzył, powinno to być wykonalne w miarę łatwo. W świecie bezpieczeństwa istnieje pojęcie hasła "jednorazowego". Jest to czasami określane jako " jednorazowe hasło."Zwykle są one ograniczone do (łatwo typowalnych) wartości ASCII. A więc [a-zA-z0-9] i kilka łatwych do wpisania symboli. jak przecinek, kropka, dwukropek i nawias. W Twoim przypadku jednak prawdopodobnie chciałbyś ograniczyć zakres do [0-9] i ewentualnie zawierać * i #.

Nie jestem w stanie wyjaĹ "niÄ ‡ wszystkich szczegĂłĹ' Ăłw technicznych jak owe kody jednorazowe sÄ ... odpowiednio generowane (lub dziaĹ ' ajÄ...). Za tym kryje się jakaś matma średniozaawansowana, którą sam bym wykastrował bez uprzedniej recenzji. Wystarczy powiedzieć, że używasz algorytmu do generowania strumienia haseł jednorazowych. Bez względu na to, jak mnay poprzednie kody znasz, następny powinien być impossibel do odgadnięcia! W Twoim przypadku po prostu użyjesz każdego hasła na liście jako losowego użytkownika kod.

Zamiast nie wyjaśniać szczegółów implementacji osobiście, skieruję Cię do 9-stronicowego artykułu, gdzie możesz przeczytać o nim sam: https://www.grc.com/ppp.htm

 0
Author: Rob Rolnick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-05 16:50:46

Wygląda na to, że masz niewypowiedziany wymóg, aby szybko ustalić, za pomocą algorytmu, że kod jest ważny. Wykluczyłoby to, że po prostu rozdajesz listę jednorazowych numerów pad.

Jest kilka sposobów, w jaki ludzie robili to w przeszłości.

  1. Stwórz klucz publiczny i klucz prywatny. Zakoduj liczby 0-999,999 za pomocą klucza prywatnego i rozdaj wyniki. Musisz dorzucić kilka losowych liczb, aby wynik wyszedł na dłużej Wersja, a będziesz musiał przekonwertować wynik z bazy 64 NA bazę 10. Po wprowadzeniu liczby przekonwertuj ją z powrotem na base64, zastosuj klucz prywatny i sprawdź, czy liczby interetingowe są mniejsze niż 1 000 000 (Odrzuć liczby losowe).
  2. użyj odwracalnej funkcji skrótu
  3. Użyj pierwszych milionów liczb z PRN zaszeregowanych według określonej wartości. Funkcja "sprawdzanie" może uzyskać ziarno i wiedzieć, że następny milion wartości są dobre. Może je generować za każdym razem i sprawdzić jeden po drugim, gdy kod jest odbierany, lub na starcie programu przechowywać je wszystkie w tabeli, posortowane ,a następnie użyć wyszukiwania binarnego (maksymalnie porównań), ponieważ jeden milion liczb całkowitych nie jest dużo miejsca.

Istnieje kilka innych opcji, ale są one powszechne i łatwe do wdrożenia.

- Adam

 0
Author: Adam Davis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-05 16:51:19

Połączyłeś się z projektem cyfry kontrolne i użycie funkcji "koduj" wydaje się dobrym rozwiązaniem. Pisze:

Encode może rzucić wyjątek, jeśli zostaną mu przekazane " złe " dane (np. nieliczbowe), podczas gdy verify zwraca tylko true lub false. Chodzi o to, że encode zwykle pobiera dane z "zaufanych" źródeł wewnętrznych( na przykład klucz bazy danych), więc powinno być całkiem zwyczajne, w rzeczywistości wyjątkowe, że złe dane są przekazywane.

Tak to brzmi podobnie jak możesz przekazać funkcję kodowania klucz bazy danych (5 cyfr, na przykład) i możesz uzyskać numer, który spełni Twoje wymagania.

 0
Author: Michael Sharek,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2008-09-05 17:13:13