document.write('
Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. /*
  2. @Author : Joel Fernandez
  3. @Web    : www.codebotic.com
  4. @Fecha  : 21/07/2015
  5. @Tema   : Implementacion del algoritmo Criba Cuadratica ( Quadratic Sieve)
  6. */
  7.  
  8. #include<iostream>
  9. #include<conio.h>
  10. #include<cstdlib>
  11. #include <algorithm>
  12. #include<math.h>
  13. #include <stdio.h>
  14. #include <vector>
  15. #include <time.h>
  16. #define MaxBase 30
  17. #define MAxAleat 35
  18.  
  19. using namespace std;
  20.  
  21.  
  22. long VectorBase[MaxBase]; // contiene los numeros que son raicez cuadradas del numero
  23. long VectorX[MAxAleat * 2];// contiene el vector de numeros (X+M)
  24. long fx[MAxAleat * 2];// contiene el vector de numeros f(x)=(X+M)^2 - n
  25. long Matriz[MAxAleat][MaxBase];//contiene la matriz binaria de numeros lisos (suaves)
  26.  
  27. long tamBase = 0,tamX = 0, tamfact = 0;
  28. long n;
  29. long *Sol;
  30. long **MatrizT;
  31.  
  32. bool esPrimo(long);
  33. long jacobi(long ,long );
  34. long func_exp(long );
  35. long *HallarBase(long );
  36. void addMatriz(long ,long );
  37. void CalcularX();
  38. long *factorizar(long );
  39. void imprimirVector(long *, long );
  40. void imprimirMatriz(long , long );
  41. long long mcd(long long  , long long  );
  42. bool obtenerSolucion();
  43. void LiberarMemoria();
  44.  
  45. /*    Funcion principal    */
  46. int main(void)
  47. {
  48.     system("color 0a");
  49.  
  50.     cout<<"\\t    ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»"<<endl;
  51.     cout<<"\\t    º                                                         º"<<endl;
  52.     cout<<"\\t    º                  Algoritmo Quadratic Sieve              º"<<endl;
  53.     cout<<"\\t    º                                                         º"<<endl;
  54.     cout<<"\\t    ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ  "<<endl;
  55.     cout<<endl<<endl;
  56.     cout<<"\\tIngrese  N: "; cin>>n;
  57.  
  58.     HallarBase(n);
  59.  
  60.     cout<<"\\n\\tLos Factores Base: \\n\\n";
  61.     imprimirVector(VectorBase,tamBase);
  62.     cout<<"\\n";
  63.  
  64.  
  65.     CalcularX();//calcula los x+m
  66.  
  67.     cout<<"\\tLos Valores de X son: \\n\\n";
  68.     imprimirVector(VectorX,tamX);
  69.     cout<<"\\n\\n";
  70.  
  71.     cout<<"\\tLos Valores y = F(x) son: \\n\\n";
  72.     imprimirVector(fx,tamX);
  73.     cout<<"\\n\\n";
  74.  
  75.     cout<<"\\tLa matriz de Factores es: \\n\\n";
  76.     imprimirMatriz(tamX,tamBase);
  77.     cout<<endl;
  78.  
  79.  
  80.  
  81.     long long x=1,y2=1;
  82.  
  83.     cout<<"\\n\\nProcesando ";
  84.  
  85.     if(obtenerSolucion()==true){
  86.  
  87.         cout<<"\\n\\nUna solucion posible es :"<<endl;
  88.  
  89.         for(int i=0;i<tamX;i++){
  90.             cout<<Sol[i]<<"  ";
  91.             if(Sol[i]==1){
  92.                 x=x*VectorX[i];
  93.                 y2=y2*fx[i];
  94.            }
  95.         }
  96.         x=x%n;
  97.         cout<<"\\n X="<<x<<endl;
  98.         long long y=sqrt(y2);
  99.         y=y%n;
  100.         cout<<"\\n Y="<<y<<endl;
  101.  
  102.         if((x-y)>n)
  103.             cout<<"\\nmcd(x-y,n)="<<mcd(n,x-y)<<endl;
  104.         else
  105.             cout<<"\\nmcd(x-y,n)="<<mcd(n,x-y)<<endl;
  106.  
  107.         if((x+y)>n)
  108.             cout<<"\\nmcd(x+y,n)="<<mcd(x+y,n)<<endl;
  109.         else
  110.             cout<<"\\nmcd(x+y,n)="<<mcd(n,x+y)<<endl;
  111.  
  112.         system("pause");
  113.  
  114.  
  115.     } else
  116.         cout<<"\\nLa solucion no tuvo exito"<<endl;
  117.  
  118.  
  119.  
  120.     LiberarMemoria();
  121.  
  122.     system("pause");
  123. }
  124.  
  125. /* Calcula el Maximo Comun Divisor */
  126. long long mcd(long long  a, long long b )
  127. {
  128.     if(b==0) return a;
  129.     else mcd(b,a%b);
  130. }
  131.  
  132.  
  133.  
  134. /* Imprime la Matriz*/
  135.  
  136. void imprimirMatriz(long x, long y){
  137.  
  138.     for(long i=0; i<x; i++){
  139.         cout<<"\\t";
  140.         for(long j=0; j<y; j++){
  141.  
  142.             cout<<Matriz[i][j]<<" ";
  143.         }
  144.         cout<<"\\n";
  145.     }
  146.     cout<<"\\n\\n";
  147.  
  148. }
  149.  
  150. /* Imprime un vector */
  151.  
  152. void imprimirVector(long *V, long tam){
  153.     cout<<"\\t";
  154.     for(long i=0; i<tam; i++){
  155.  
  156.         cout<<V[i]<<", ";
  157.  
  158.     }
  159.     cout<<"\\n";
  160.  
  161. }
  162.  
  163.  
  164. /*Calcula si es primo o no*/
  165. bool esPrimo(long x){
  166.  
  167.     if (x <= 1) return false;
  168.      for (long i = 2; i*i <= x; ++i) {
  169.           if (x%i == 0) return false;
  170.      }
  171.      return true;
  172.  
  173. }
  174.  
  175. /* funcion para determinar si a es raiz cuadrada de n*/
  176. long jacobi(long a,long n)
  177. {
  178.    long a1 = 1,n1 = 0,s,j,sj,e ,p;
  179.    long b=2;
  180.  
  181.    if(a==0 || a == 1)
  182.    {
  183.         return a;
  184.    }
  185.    else
  186.    {
  187.        e = func_exp(a);
  188.        p = (long)pow(2,e);
  189.        a1= (long)(a/p);
  190.  
  191.        if(e%2==0)
  192.        {
  193.             s=1;
  194.        }
  195.        else
  196.        {
  197.             if((((n-1)%8)==0)||(((n-7)%8)==0))
  198.             {
  199.                 s=1;
  200.             }
  201.             else
  202.             {
  203.                 if((((n-3)%8)==0)||(((n-5)%8)==0))
  204.                 {
  205.                     s=-1;
  206.                 }
  207.             }
  208.        }
  209.        if((((n-3)%4)==0)&&(((a1-3)%4)==0))
  210.        {
  211.             s=-s;
  212.        }
  213.        n1=(n%a1);
  214.        if(a1==1)
  215.        {
  216.             return s;
  217.        }
  218.        else
  219.        {
  220.             return s*jacobi(n1,a1);
  221.        }
  222.     }
  223. }
  224.  
  225. /* Funcion para Encotrar la Base de primos */
  226.  
  227. long* HallarBase(long n)
  228. {
  229.     long i,j;
  230.     VectorBase[0] = -1;
  231.     VectorBase[1] = 2;
  232.     for(i=3,j=2;i<MaxBase;i++)
  233.     {
  234.         if(esPrimo(i)==true)
  235.         {
  236.             if(jacobi(n,i)==1)//hallamos el jacobi para filtrar los primos que pertenecen a la base
  237.             {
  238.                 VectorBase[j++]=i;
  239.             }
  240.         }
  241.     }
  242.     tamBase=j;
  243. }
  244.  
  245. /* agrega un vector de binarios a matriz*/
  246. void addMatriz(long fact[], long inicio,long h)
  247. {
  248.     for(long i=inicio;i<tamfact;i++)
  249.     {
  250.         Matriz[h][i-1]=fact[i];
  251.     }
  252. }
  253.  
  254.  
  255. /*calcula los x+m */
  256. void CalcularX()
  257. {
  258.  
  259.     long raiz=(long)sqrt(n);
  260.     long i=raiz-MAxAleat;// i es el rango menor de la criba
  261.     long j=raiz+MAxAleat;// j es el rango mayor de la criba
  262.     long h=0,w=0,y;
  263.  
  264.     while(i!=j)
  265.     {
  266.         long *factores = new long[tamBase+1];
  267.         y=(i*i)-n;// (x+m)^2 - n
  268.         if(y!=0)
  269.         {
  270.             factores = factorizar(y);
  271.             if(factores[0]==1)
  272.             {
  273.                 VectorX[h]=i;
  274.                 fx[h]=y;
  275.                 addMatriz(factores,1,h);
  276.                 h++;
  277.             }
  278.         }
  279.         i++;
  280.     }
  281.  
  282.     tamX = h;
  283. }
  284.  
  285. /* factoriza a x+m en los primos de la base y devuelve en vector binario*/
  286. long *factorizar(long x)
  287. {
  288.     long *Vf = new long[tamBase+1];
  289.     Vf[0]=0;
  290.     long cont=0,j=2,i=1;
  291.  
  292.     (x < 0) ? Vf[1] = 1 : Vf[1] = 0;
  293.  
  294.     for(;i<tamBase;)
  295.     {
  296.         if(x%VectorBase[i]==0)//hallamos los exponentes de cada vector
  297.         {
  298.             cont++;
  299.             x=x/VectorBase[i];
  300.             continue;
  301.         }
  302.         Vf[j++]=cont%2;
  303.         cont=0;
  304.         i++;
  305.     }
  306.     tamfact = j;
  307.     if(x==1 || x==-1)
  308.     {
  309.         Vf[0] = 1;
  310.     }
  311.     return Vf;
  312. }
  313. /*se utiliza en jacobi para obtener el contador del exponente*/
  314. long func_exp(long a)
  315. {
  316.    long e=0;
  317.    while(a%2==0)
  318.    {
  319.         a=a/2;
  320.         e++;
  321.    }
  322.    return e;
  323. }
  324.  
  325.  
  326.  
  327. /*liberamos memoria de la matriz transpuesta*/
  328. void LiberarMemoria(){
  329.  
  330.    for(long i = 0; i < tamX; i++) delete[] MatrizT[i];
  331.    delete[] MatrizT;
  332. }
  333.  
  334.  
  335. /*Obtenemos una solucion */
  336. bool obtenerSolucion(){
  337.     int q=0;
  338.     bool band=false;
  339.     Sol=new long[tamX];
  340.     long *aux2=new long[tamBase];
  341.     int cont;
  342.  
  343.     MatrizT = new long*[tamBase];
  344.     for(int i = 0; i < tamBase; i++)
  345.       MatrizT[i] = new long[tamX];
  346.  
  347.     /*obtenemos la transpuesta*/
  348.     for(long i=0; i<tamBase; i++){
  349.         for(long j=0; j<tamX; j++){
  350.  
  351.             MatrizT[i][j]=Matriz[j][i];
  352.         }
  353.  
  354.     }
  355.  
  356.     while(band==false||q!=100000){
  357.  
  358.             /*generar matriz aleatoria*/
  359.  
  360.             for(int i=0;i<tamX;i++){
  361.  
  362.                 Sol[i]=rand()%(2);
  363.             }
  364.             //cout<<endl;
  365.             //for(int i=0;i<tamX;i++)cout<<Sol[i];
  366.  
  367.             int aux=0;
  368.             for(long i=0; i<tamBase; i++){
  369.                 for(long j=0; j<tamX; j++){
  370.  
  371.                     aux+=MatrizT[i][j]*Sol[j];
  372.                 }
  373.                 aux2[i]=aux%2;
  374.  
  375.             }
  376.             cont=0;
  377.  
  378.             /*verificamos que el vector final sea cero*/
  379.             for(int i=0;i<tamBase;i++){
  380.                 if(aux2[i]!=0){
  381.                    cont++;
  382.                 }
  383.             }
  384.  
  385.             if(cont==0){
  386.                band =true;
  387.                return true;
  388.              }
  389.  
  390.             q++;
  391.     }
  392.  
  393.     if(q<=100000){// si no se encuentra soluciones luego de 10000 numeros aleatorios retorna no hay solucion
  394.         return false;
  395.     }
  396.  
  397. }
');