Test Fermata jest to test probabilistyczny, którego wynik może określić czy dana liczba jest złożona czy prawdopodobnie jest (pseudo)pierwsza. Innymi słowy jest to krótki test czy dana liczba ma szansę być pierwsza, ale test Fermata nie rozstrzyga czy jest.
Mała Teoria Fermata stwierdza, że jeśli p jest pierwsze oraz a nie dzieli p to:
ap - 1 ≡p 1
W celu sprawdzenia czy p jest liczbą pierwszą to wybieramy losową wartość a z przedziału [2, p - 2], a następnie sprawdzamy czy dana równość zachodzi. Test wykonywany jest dla więcej niż jednej wartości a. Jeśli pomimo
Przypuśćmy, że chcemy sprawdzić czy p = 123 jest liczbą pierwszą. Na początku określamy, że przedział losowanie wartości a to [2, 121]. Przeprowadźmy maksymalnie dziesięć testów, aby sprawdzić czy 123 ma szansę być liczbą pierwszą.
a | Test | Wynik |
---|---|---|
65 | 65122 ≡123 43 | Możliwe, że (pseudo)pierwsza |
47 | 47122 ≡123 118 | Możliwe, że (pseudo)pierwsza |
97 | 97122 ≡123 61 | Możliwe, że (pseudo)pierwsza |
83 | 83122 ≡123 1 | 123 to liczba złożona! |
W czwartym teście została znaleziona taka liczba a, że test wykazał złożoność liczby p. Jednak, gdyby wartość 83 nie została wylosowana to możnaby uznać p za liczbę (pseudo)pierwszą, ale dowód na jej pierwszość należałoby przeprowadzić oddzielnie.
Zanim zacznie się pisać test Fermata warto posiadać algorytm do wyliczania potęgi modulo. Ze względu na bardzo wysokie potęgi zakresy podstawowych typów danych mogą okazać się za małe. W celu rozwiązania tego problemu oraz przyśpieszenia procesu obliczania potęgi można skorzystać z poniższego kodu:
Algorytm wykorzystuje fakt, że reszta z dzielenia a·a mod m to (a mod m)(a mod m) mod m. Dodatkowo zoptymalizowany jest proces mnożenia. Jeśli potęga jest nieparzysta to wynik jest mnożony tylko raz przez bazę, a baza jest podnoszona do kwadratu co zmniejsza potęge x dwa razy.
Przykładowy kod do przeprowadzenia testów Fermata został zamieszczony poniżej. Pozwala on na dostosowanie ilości prób (zmienna prob), które mają zaprzeczyć podejrzenia o pierwszości danej liczby p.
Poniższy fragment programu wczytuje od użytkownika liczbę, a następnie sprawdza czy dana liczba jest prawdopodobnie pierwsza.
W powyższym algorytmie może się zdarzyć, że ta sama wartość a zostanie sprawdzona kilka razy. Napisz algorytm w taki sposób, aby do takich sytuacji nie dochodziło.