/* The following functions are (c) 2000 by John M Hanna and are * released under the terms of the Gnu Public License. * You must freely redistribute them with their source -- see the * GPL for details. * -- Latest version found at http://sourceforge.net/projects/shop-js */ // ---------------------- Arbitrary Precision Math // badd(a,b), bsub(a,b), bmul(a,b), bdiv(a,b), bmod(a,b), // brshift(a), beq(a,b) // set the base... 32bit cpu -> bs=16, 64bit -> bs=32 // bm is the mask, bs is the shift //bm=0xf; bs=4; // low base useful for testing if digits handled ok bs=28; bx2=1<>1; bd=bs>>1; bdm=(1 << bd) -1 function badd(a,b) { // binary add var al=a.length, bl=b.length if(al < bl) return badd(b,a) var c=0, r=[], n=0 for(; n>>=bs } for(; n>>=bs } if(c) r[n]=c return r } function beq(a,b) { // returns 1 if a == b if(a.length != b.length) return 0 for(var n=a.length-1; n>=0; n--) if(a[n] != b[n]) return 0 return 1 } function bsub(a,b) { // binary subtract var al=a.length, bl=b.length, c=0, r=[] if(bl > al) {return []} if(bl == al) { if(b[bl-1] > a[bl-1]) return [] if(bl==1) return [a[0]-b[0]] } for(var n=0; n>=bs } for(;n>=bs } if(c) {return []} if(r[n-1]) return r while(n>1 && r[n-1]==0) n--; return r.slice(0,n) } function bmul(a,b) { // binary multiply b=b.concat([0]) var al=a.length, bl=b.length, r=[], n,nn,aa, c, m var g,gg,h,hh, ghhb for(n=al+bl; n>=0; n--) r[n]=0 for(n=0; n>bd; h=aa & bdm m=n for(nn=0; nn>bd; g=g & bdm //(gg*2^15 + g) * (hh*2^15 + h) = (gghh*2^30 + (ghh+hgg)*2^15 +hg) ghh = g * hh + h * gg ghhb= ghh >> bd; ghh &= bdm c += r[m] + h * g + (ghh << bd) r[m] = c & bm c = (c >> bs) + gg * hh + ghhb } } } n=r.length if(r[n-1]) return r while(n>1 && r[n-1]==0) n--; return r.slice(0,n) } function blshift(a,b) { var n, c=0, r=[] for(n=0; n>=bs } if(c) r[n]=c return r } function brshift(a) { var c=0,n,cc, r=[] for(n=a.length-1; n>=0; n--) { cc=a[n]; c<<=bs r[n]=(cc | c)>>1 c=cc & 1 } while(r.length > 1 && r[r.length-1]==0) { r=r.slice(0,-1) } this.a=r; this.c=c return this } function bdiv(p,m) { // binary divide & modulo var a=p.concat() var dig,mm,n,guess,d,v this.q=[] // figure how many places we'll divide dig=a.length-m.length+1 mm=[] for(n=0; n=0; n--) this.q[n]=0 var mmm=[], mmn=0, t for(n=0; n>=1 if(posi==0) { posi=bx dig-- } } while(dig >= 0) while(this.q.length > 1 && this.q[this.q.length-1]==0) this.q=this.q.slice(0,-1) this.mod=a return this } function bmod(p,m) { // binary modulo if(m.length==1) { if(p.length==1) return [p[0] % m[0]] if(m[0] < bdm) return [simplemod(p,m[0])] } var r=bdiv(p,m) return r.mod } function simplemod(i,m) { // returns the mod where m < 2^bd if(m>bdm) alert('simplemod error') var c=0, v for(var n=i.length-1; n>=0; n--) { v=i[n] c=((v >> bd) + (c<=0; n--) mu[n]=0; mu=bdiv(mu,m).q for(n=0; n 0) { return bmod2(x.slice(0,xl).concat(bmod2(x.slice(xl),m,mu)),m,mu) } var ml1=m.length+1, ml2=m.length-1,rr //var q1=x.slice(ml2) //var q2=bmul(q1,mu) var q3=bmul(x.slice(ml2),mu).slice(ml1) var r1=x.slice(0,ml1) var r2=bmul(q3,m).slice(0,ml1) var r=bsub(r1,r2) //var s=('x='+x+'\nm='+m+'\nmu='+mu+'\nq1='+q1+'\nq2='+q2+'\nq3='+q3+'\nr1='+r1+'\nr2='+r2+'\nr='+r); if(r.length==0) { r1[ml1]=1 r=bsub(r1,r2) } for(var n=0;;n++) { rr=bsub(r,m) if(rr.length==0) break r=rr if(n>=3) return bmod2(r,m,mu) } return r } // conversion functions: // text to binary and binary to text, text to base64 and base64 to text // OK, so this isn't exactly base64 -- fix it if you care b64s='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_"' b94s=''; for(var n=33; n<127; n++) b94s+=String.fromCharCode(n) function radix(base, a, newbase, wantarray) { // converts a from base ba to base bb // convert a to array & parse out invalid chars var n=a.length-1,m=0,p=[],nm=a.length if(a.constructor==Array) { p=a.concat() } else if(base <= 64) { for(n=0; n=0; n--) if((c=b64s.indexOf(a.charAt(n)))>=0) p[m++]=c } else if(base <= 94) { for(n=0; n=0) p[m++]=c } else if(base <= 256) { for(n=0; n 256; base='+base) return 0 } if(base=0; n--) { for(vn=0; vn=1) { if(v.length == vn+1) v[vn+1]=0 v[vn+1]+=Math.floor(v[vn]/newbase) v[vn]%=newbase } } v[0]+=p[n] } for(vn=0; vn=1) { if(v.length == vn+1) v[vn+1]=0 v[vn+1]+=Math.floor(v[vn]/newbase) v[vn]%=newbase } } } else if(base > newbase) { var t=p var pn=0, p=[], v var pe=Math.ceil(t.length*Math.log(base)/Math.log(newbase)) while(pn=0; n--) { if(t[n] || v) { t[n] += v*base v=t[n]%newbase t[n]=Math.floor(t[n]/newbase) } } p[pn++]=v } v=p } // out while(v.length && v[v.length-1]==0) v=v.slice(0,-1) n=0; m=v.length var s='' if(wantarray || newbase > 256) { return v } else if(newbase <= 64) { for(;n=0; x--) { x2=x % kl y=(key.charCodeAt(x % key.length) + s[x2] + y) % 256 t=s[x2]; s[x2]=s[y]; s[y]=t } x=0; y=0; var z="" for (x=0; x