// Gli identificatori HTML usati:
var zxcontrollopseudoprimo="xcontrollopseudoprimo";
var zaggiornamento="aggiornamento",inputzva="va",inputzvb="vb",inputzvm="vm";
var zm1="m1",zm2="m2";
var zxcifre="xcifre",zxcifrx="xcifrx",zxbase="xbase";
//
// Ogni intero č una Array di lunghezza CIFRE con
// l'elemento 0 come cifra meno significativa.
var CIFRE=8;
// Attenzione: in Javascript le cifre della base
// non possono essere pių di 15.
var CIFRX=9;
//
// Non modificare nulla di quanto segue
// se non facendo molta, molta attenzione...
var BASE=Math.pow(10,CIFRX);
//
function imposto(x,c){
var j;
x[0]=c;
for(j=1;CIFRE>j;j++) x[j]=0;
}
//
var zero,aa,bb,mm,rr,bs,as,bp,mp,us,up;
function inizializzolib(){
zero=new Array(CIFRE);
imposto(zero,0);
aa=new Array(CIFRE);
imposto(aa,0);
bb=new Array(CIFRE);
imposto(bb,0);
mm=new Array(CIFRE);
imposto(mm,0);
rr=new Array(CIFRE);
imposto(rr,0);
bs=new Array(CIFRE);
imposto(bs,0);
as=new Array(CIFRE);
imposto(as,0);
bp=new Array(CIFRE);
imposto(bp,0);
mp=new Array(CIFRE);
imposto(mp,0);
us=new Array(CIFRE);
imposto(us,0);
up=new Array(CIFRE);
imposto(up,0);
mm[0]=8191;
}
//
// Inizializzo quando tutto e' pronto con una onload...
// inizializzo();
//
// Stampa bene il numerone con la cifra
// meno significativa a destra.
// Senza questa funzione la cifra meno significativa
// essendo l'elemento zeresimo del vettore, starebbe
// a sinista.
//
function zahlen(a){
var j,t,s,n=a.length;
s=" ";
for(j=n-1;j>=0;j--){
if(0>a[j]) break;
t="00000000000000000000"+a[j];
s+=String.fromCharCode(729)+t.slice(t.length-CIFRX,t.length);
}
return s;
}
//
// Aggiunge una costante al numerone a col vincolo
// che il valore assoluto della costante b deve
// essere minore della base.
//
function somcomod(r,a,b,m){
var j,rs;
rs=Math.abs(b);
if(rs>=BASE) alert("Costante fuori limite "+b);
for(j=0;CIFRE>j;j++){
r[j]=rs+a[j]-m[j];
if(r[j]>=BASE) { r[j]-=BASE; rs=1; }
else if(0>r[j]) { r[j]+=BASE; rs=-1; }
else rs=0;
}
if(0>rs){
rs=0;
for(j=0;CIFRE>j;j++){
r[j]+=rs+m[j];
if(r[j]>=BASE) { r[j]-=BASE; rs=1; }
else rs=0;
}
}
return r;
}
//
// Somma modulare di due numeroni a e b modulo m.
//
function sommamod(r,a,b,m){
var j,rs;
rs=0;
for(j=0;CIFRE>j;j++){
r[j]=rs+a[j]+b[j]-m[j];
if(r[j]>=BASE) { r[j]-=BASE; rs=1; }
else if(0>r[j]) { r[j]+=BASE; rs=-1; }
else rs=0;
}
if(0>rs){
rs=0;
for(j=0;CIFRE>j;j++){
r[j]+=rs+m[j];
if(r[j]>=BASE) { r[j]-=BASE; rs=1; }
else rs=0;
}
}
return r;
}
//
// Sottrazione al numerone a della costante b che
// in valore assoluto non deve superare a base.
//
function difcomod(r,a,b,m){
var j,rs;
rs=-Math.abs(b);
if(0>b) alert("Costante negativa "+b);
for(j=0;CIFRE>j;j++){
r[j]=rs+a[j];
if(0>r[j]) { r[j]+=BASE; rs=-1; }
else rs=0;
}
if(0>rs){
rs=0;
for(j=0;CIFRE>j;j++){
r[j]+=rs+m[j];
if(r[j]>=BASE) { r[j]-=BASE; rs=1; }
else rs=0;
}
}
// alert(zahlen(r));
return r;
}
//
// Differenza tra due numeroni ossia a-b modulo m.
//
function diffemod(r,a,b,m){
var j,rs;
rs=0;
for(j=0;CIFRE>j;j++){
r[j]=rs+a[j]-b[j];
if(0>r[j]) { r[j]+=BASE; rs=-1; }
else rs=0;
}
if(0>rs){
rs=0;
for(j=0;CIFRE>j;j++){
r[j]+=rs+m[j];
if(r[j]>=BASE) { r[j]-=BASE; rs=1; }
else rs=0;
}
}
return r;
}
//
// Fa il test se il numero non vale esattamente 0.
//
function nonzero(a){
for(j=CIFRE-1;j>=0;j--){
if(a[j]!=0) return true;
}
return false;
}
//
// Fa il test se il numero non vale esattamente 1.
//
function nonuno(a){
for(j=CIFRE-1;j>0;j--){
if(a[j]!=0) return true;
}
if(a[0]!=1) return true;
return false;
}
//
function menuno(a,N){
for(j=CIFRE-1;j>0;j--){
if(a[j]!=N[j]) return false;
}
if(a[0]+1!=N[0]) return false;
return true;
}
//
function dimezzo(a){
var j,rs;
rs=0;
for(j=CIFRE-1;j>=0;j--){
a[j]=a[j]+rs;
if(a[j]%2==0){
a[j]=a[j]/2;rs=0;}
else {a[j]=(a[j]-1)/2;rs=BASE;}
}
return rs;
}
//
function numeropari(a){
return (a[0]%2==0);
}
//
function trascrivo(x,a){
var j;
for(j=0;CIFRE>j;j++) {
if(a[j]>=BASE) alert("Cifra starata: "+j+"\n"+a);
x[j]=a[j]%BASE;
}
}
//
function prodotto(vs,aa,bb,p){
var res;
trascrivo(bs,bb);
trascrivo(as,aa);
imposto(vs,0);
do {res=dimezzo(as);
if(res>0) sommamod(vs,vs,bs,p);
sommamod(bs,bs,bs,p);
}while(nonzero(as));
return vs;
}
//
function potenza(vp,a,n,p){
var res;
imposto(vp,1);
trascrivo(bp,a);
trascrivo(mp,n);
do {res=dimezzo(mp);
if(res>0) prodotto(vp,bp,vp,p);
prodotto(bp,bp,bp,p);
}while(nonzero(mp));
return vp;
}
//
function pseudoprimoforte(a,N){
var j=0;
var sb=new Array(N.length);
var vp=new Array(a.length);
trascrivo(sb,N);
difcomod(sb,sb,1);
do{ dimezzo(sb);
j++; } while(numeropari(sb));
potenza(vp,a,sb,N);
if(!nonuno(vp)) return [ true,a,N];
do{ if(menuno(vp,N)) return [ true,a,N];
sommamod(sb,sb,sb,N);
prodotto(vp,vp,vp,N);
j--; } while(j>0);
return [ false,a,N];
}
//
var ntentativi=0,tentativi=[2,3,5,7,9,13,23];
var inicontrollo=0,vcontrolli=[2,20,100,1000];
//
var colori=0;
var vcolori=["red","green","blue","navy","magenta"];
function numerotentativi(questo){
ntentativi=(ntentativi+1)%tentativi.length;
questo.value=" Ora faccio "+tentativi[ntentativi]+" prove ( clicca per cambiare ) ";
colori=(colori+1)%vcolori.length;
questo.style.background=vcolori[colori];
}
function primocontrollo(questo){
inicontrollo=(inicontrollo+1)%vcontrolli.length;
questo.value=" Ora parto da "+(2*vcontrolli[inicontrollo]+1)+" ( clicca per cambiare ) ";
colori=(colori+1)%vcolori.length;
questo.style.background=vcolori[colori];
}
//
function controllopseudoprimo(){
var t,r,x,a,risu,ss="";
x=document.getElementById(inputzvm);
risu=document.getElementById(zxcontrollopseudoprimo)
//
numerone(mm,x.value);
a=new Array(mm.length);
trascrivo(a,zero);
for(t=vcontrolli[inicontrollo];
vcontrolli[inicontrollo]+tentativi[ntentativi]>t;t++){
a[0]=2*t+1;
r=pseudoprimoforte(a,mm);
if(r[0])ss+="\u003cb\u003eOttengo: "+r[0]+
"\u003c/b\u003e\u003cbr/\u003ebase="+zahlen(r[1])+
"\u003cbr/\u003eIndagato="+zahlen(r[2])+"\u003cbr/\u003e";
else ss+="\u003cb\u003eNON PRIMO ! Ottengo: "+r[0]+
"\u003c/b\u003e\u003cbr/\u003ebase="+zahlen(r[1])+
"\u003cbr/\u003eIndagato="+zahlen(r[2])+"\u003cbr/\u003e";
// if(!confirm("Ottengo: "+r[0]+"\nbase="+r[1]+"\nIndagato="+r[2]) ) break;
}
risu.innerHTML=ss;
}
//
//
//
function numerone(r,a){
var j,k,s="",n=a.length;
for(j=0;CIFRE>j;j++) r[j]=0;
for(j=0;n>j;j++){
k=a.charCodeAt(j);
if(k>32)s+=String.fromCharCode(k);
}
n=s.length;
k=1;
kk=0;
for(j=n-1;j>=0;j--){
r[kk]=r[kk]+(s.charCodeAt(j)+2)%10*k;
k*=10;
if(k==BASE){k=1;kk=Math.min(kk+1,CIFRE-1)}
}
}
//
function fase(){
var h=document.getElementById(zaggiornamento);
var n=parseInt(h.innerHTML);
h.innerHTML=n+1;
}
//
function calcola(){
var x;
x=document.getElementById(inputzva);
numerone(aa,x.value);
x=document.getElementById(inputzvb);
numerone(bb,x.value);
x=document.getElementById(inputzvm);
numerone(mm,x.value);
//
x=document.getElementById(zm1);
x.innerHTML="aa+bb mod mm ="+zahlen(sommamod(rr,aa,bb,mm))+
"\u003cbr/\u003e aa−bb mod mm ="+zahlen(diffemod(rr,aa,bb,mm));
x=document.getElementById(zm2);
x.innerHTML="aa·bb mod mm ="+zahlen(prodotto(up,aa,bb,mm))+
"\u003cbr/\u003e aa\u003csup\u003e\u003csmall\u003ebb\u003c/small\u003e\u003c/sup\u003e"+
" mod mm ="+ zahlen(potenza(up,aa,bb,mm)) +
"\u003cbr/\u003eaa\u003csup\u003e\u003csmall\u003emm−2"+
"\u003c/small\u003e\u003c/sup\u003e mod mm ="+
zahlen(potenza(up,aa,difcomod(us,zero,2,mm),mm));
return true;
}
//
// Bisogna chiamare questa funzione onload.
//
function inizializzo(){
var obj;
inizializzolib();
obj=document.getElementById(zxcifre);
obj.innerHTML=CIFRE;
obj=document.getElementById(zxcifrx);
obj.innerHTML=CIFRX;
obj=document.getElementById(zxbase);
obj.innerHTML=BASE;
}
//
// Da definire in HTML :
//
// zxcontrollopseudoprimo,zaggiornamento,inputzva,inputzvb,inputzvm,zm1,zm2,
// zxcifre,zxcifrx,zxbase;
//
// Riassegnare i loro valori o usare quelli predefiniti
//