Primtal
Att ta reda på om ett tal är ett primtal eller ej är lite
klurigare än man kan tro. Egentligen handlar det bara om att
försäkra sig om att talet inte är jämnt delbart med något lägre
tal vilket i teorin inte är svårt alls. Men om man hanterar
väldigt stora tal som till exempel nycklar vid kryptering och
liknande så blir det i praktiken ganska tidsödande att testa alla
lägre tal.
Eratosthenes såll är en naiv algoritm som utvecklades av den gamla
greken Eratosthenes runt år -200. Algoritmen tar en övre gräns och
sållar bort allt som inte är primtal under gränsen. Efteråt finns
bara primtalen kvar. Själva sållningen går till så att man börjar
från 2 och plockar bort alla tal under gränsen som är delbara med
2. Sen tar man 3, plockar bort alla tal delbara med 3, fortsätt
med 4 ... osv upp till gränsen. På kodsidan
finns algoritmen implementerad i flera olika programmeringsspråk.
Om man nu bara är intresserad av att testa om ett enda tal
(x ) är ett primtal så kan man använda en förenklad
version av Eratosthenes såll. Det räcker då att kolla
att x inte är jämnt delbart med något tal
under x med en loop som den nedan.
bool testForPrime(int x)
{
for (int i = 2; i < x; i++) {
if (x % i == 0) {
// Inte primtal.
return false;
}
}
// Primtal!!
return true;
}
Det är ganska lätt att förbättra prestandan i Eratosthenes såll
genom att utnyttja det vi vet om primtal och delbarhet. Till
exempel vet vi att inga jämna tal förutom två kan vara primtal, så
givet att x!=2 måste LSB vara ett för att det ens ska
vara värt att testa något. Givet det vet vi också
att x inte kan vara jämnt delbart med något tal
större än x/3 . Vi får då ett lite effektivare test.
bool testForPrime(int x)
{
int upperLimit;
// Inga jämna tal förutom två kan vara primtal
if (x == 2)
return true;
else if (x & 1 == 0)
return false;
// Testa endast udda tal upp till x/3
upperLimit = x / 3;
for (int i = 3; i <= upperLimit; i += 2) {
if (x % i == 0) {
// Inte primtal.
return false;
}
}
// Primtal!!
return true;
}
Stora primtal
Om det nu är kryptologi man är ute efter och vill testa riktigt
stora tal (tal med 30-40 siffror) så är dessa metoder inte
praktiska eftersom de tar för lång tid. En populär metod som ofta
används för generering av nycklar vid till exempel RSA-kryptering
är witness.
Witness är en algoritm som kontrollerar om ett tal inte
kan vara ett primtal. Om algoritmen svarar sant är talet
garanterat inte ett primtal, om resultatet är falskt kan det vara
ett primtal. Sannorlikheten för att witness ska svara fel är
mindre än 0,5. Detta innebär att om algoritmen anropas ett antal
gånger i rad och den svarar falskt varje gång så kan man till slut
vara ganska säker på att det är ett primtal. Det är naturligtvis
en slump inblandad här, annars skulle ju svaret alltid vara det
samma.
Algoritmen finns implementerad
på kodsidan. Den anropas med två
tal, slump och prima . prima
är talet vi vill testa om det kan vara ett primtal
och slump är ett slumptal som är lägre
än prima . Eftersom slump ska vara lägre
än prima och det inte fungerar så bra med 0 och 1 så
funkar denna implementation av algoritmen inte jättebra på de
lägsta talen (1 kommer till exempel att klassas som "inte
primtal"). Men eftersom vi är ute efter riktigt stora tal här så
kanske det inte gör så mycket.
Back to index |