Ein weiteres Beispiel für einen probabilistischen Primzahltest ist der
Algorithmus von Robert Solovay und Volker Strassen. In diesem Algorithmus
wird das Jacobi-Symbol
Dieser Algorithmus ist in der C-Funktion long jacobi(long a,long b) implementiert.
Der Algorithmus testet folgendermaßen, ob eine Zahl

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#define DURCHLAEUFE 10
/****************************************************************/
/* long random32(long p) */
/* übergebener Parameter: long p */
/* Rückgabewert: long */
/* Die Funktion random() kann nur mit 16-Bit-Integerzahlen */
/* arbeiten. */
/* Die Funktion long random32(long) vergrößert diesen */
/* Zahlenbereich auf 32 Bit und benutzt dafür die */
/* random-Funktion. */
/****************************************************************/
long random32(long p)
{
int int1,int2;
long a;
int1=p>>16;
int2=random(int1);
a=int2;
a<<=16;
int1=p & 0x0000FFFF;
int2=random(int1);
a|=int2;
return (a);
}
/****************************************************************/
/* long ggt(long x,long y) */
/* übergebene Parameter: long x, long y */
/* Rückgabewert: long */
/* Die Funktion ggt berechnet den größten gemeinsamen Teiler */
/* zweier eingegebener 32-Bit-Integerzahlen mit dem Euklidschen */
/* Algorithmus und gibt ihn zurück. */
/****************************************************************/
long ggt(long x,long y)
{
long g;
if (x<0)
x=-x;
if (y<0)
y=-y;
if (x+y==0)
{
printf("\nFehler!\n");
exit(1);
}
g=y;
while (x>0)
{
g=x;
x=y%x;
y=g;
}
return (g);
}
/****************************************************************/
/* long exponent(long x, long y, long n) */
/* übergebene Parameter: long x, long y, long n */
/* Rückgabewert: long */
/* Die Funktion berechnet x hoch y mod n und arbeitet mit dem */
/* Prinzip der Verkettung oder binärem Quadrieren und */
/* Multiplizieren. */
/* Das Ergebnis wird als Rückgabewert zurückgegeben. */
/****************************************************************/
long exponent(long x,long y, long n)
{
long s,t,u;
int i;
s=1;
t=x;
u=y;
/* Schleife ausführen, solange u ungleich 0 ist */
while (u)
{
/* Wenn das unterste Bit der Zahl 1 ist */
if (u&1)
s=(s*t)%n;
/* Die Bits von u um 1 nach rechts schieben */
u>>=1;
t=(t*t)%n;
}
return (s);
}
/****************************************************************/
/* long jacobi(long a, long b) */
/* übergebene Parameter: long a, long b */
/* Rückgabewert: long */
/* Die Funktion jacobi berechnet das Jacobi-Symbol für zwei */
/* 32-Bit-Integerzahlen und gibt es als Rückgabewert zurück. */
/****************************************************************/
long jacobi(long a,long b)
{
long g;
if ((b%2)!=1)
printf("\nFehler! b gerade!\n");
if (a>=b) a%=b;/* Regel 4 */
if (a==0) return (0); /* Definition 2 */
if (a==1) return (1); /* Regel 1 */
if (a<0)
if (((b-1)/2)%2 == 0)
return (jacobi(-a,b));
else
return (-jacobi(-a,b));
if (a%2==0) /* a ist gerade */
if (((b*b-1)/8)%2==0)
return (jacobi(a/2,b));
else
return (-jacobi(a/2,b));/* Nach den Regeln 3 und 2 */
g=ggt(a,b);
if (g==a) /* a geht in b auf */
return (0); /* nach Regel 5 */
else
if (g!=1)
return (jacobi(g,b)*jacobi(a/g,b)); /* nach Regel 2 */
else
if ((((a-1)*b-1)/4)%2==0)
return (jacobi(b,a)); /* nach Regel 6a */
else
return (-jacobi(b,a)); /* nach Regel 6b */
}
/****************************************************************/
/* int solovay_strassen(long p,int t) */
/* übergebene Parameter: long p, int t */
/* Rückgabewert: int */
/* Die Prozedur testet die Long-Int-Zahl p mit dem */
/* probabilistischen Primzahltest von Robert Solovay und Volker */
/* Strassen auf Primzahleigenschaften. Der Algorithmus wird */
/* iterativ mehrmals durchlaufen. */
/* Die übergebene Variable t gibt die Zahl der Durchläufe an. */
/* Ist die Zahl keine Primzahl, wird 0 zurückgegeben, wenn die */
/* Zahl die Tests bestanden hat, also wahrscheinlich prim ist, */
/* wird 1 zurückgegeben. */
/****************************************************************/
int solovay_strassen(long p,int t)
{
int i,int1,int2;
long a,j,jac;
/* Die Schleife wird t=i - mal wiederholt */
for (i=t; i>=0; i--)
{
/* a ist eine Zufallszahl kleiner p */
a=random32(p);
if (ggt(a,p)!=1)
return (0);
j=exponent(a,(p-1)/2,p);
/* Das Jacobi-Symbol von a und p wird berechnet */
jac=jacobi(a,p);
/* Wenn j ungleich jac ist p definitiv nicht prim */
if (j!=jac)
return (0);
}
/* p hat alle Testdurchläuufe bestanden
und ist wahrscheinlich prim */
return (1);
}
/****************************************************************/
/* Hauptprozedur */
/****************************************************************/
void main(void)
{
long zahl;
randomize();
/* Eine zufällige Zahl kleiner 2147483647 wird erzeugt. Weil
random() einen int-Wert zurückgibt, wird die 32-Bit-Zahl zahl
mit der Funktion random32() aus dem Bitmuster zweier int-Zahlen
erzeugt */
zahl=random32(0x7FFFFFFF);
/* Das höchstwertigste Bit der Zahl wird auf Null gesetzt,
damit die signed long - Zahl nicht negativ ist.
Dann wird das niederwertigste und das zweit-höchstwertige Bit auf 1
gesetzt, damit sichergestellt ist, daß die Zahl groß und
ungerade ist */
zahl &= 0x7FFFFFFF;
zahl |= 0x40000001;
/* Der Solovay-Strassen-Test wird auf die Zahl angewendet.
Der Test wird DURCHLAEUFE-mal durchlaufen. */
if (solovay_strassen(zahl,DURCHLAEUFE))
printf("\n%ld ist vermutlich eine Primzahl. \n",zahl);
else
printf("\n%ld ist keine Primzahl. \n",zahl);
getch();
}