找回密码
 欢迎注册
查看: 7346|回复: 11

[分享] 找到几个数论算法的源代码

[复制链接]
发表于 2008-11-30 21:44:28 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
http://www.mindspring.com/~pate/course/chap09.html
APRCL.c
还少一个大数的库
似乎在lip.h里定义的
  1. /*
  2.   Author:  Pate Williams (c) 1997

  3.   Lucas-Lehmer primality test.
  4.   See "Implementation of a New Primality Test",
  5.   Mathematics of Computation, Volume 48, Number 177,
  6.   January 1987, pages 103 - 121 by H. Cohen and
  7.   A. K. Lenstra.
  8. */

  9. #include <ctype.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include "lip.h"

  13. #define BOUND 1000000l
  14. #define t 25200l

  15. int trial_division(long bound, verylong zn,
  16.                    long *lm, long *lmSize,
  17.                    long *lp, long *lpSize,
  18.                    verylong *zfm,
  19.                    verylong *zfp,
  20.                    verylong *znp,
  21.                    verylong *znm,
  22.                    verylong *zrm,
  23.                    verylong *zrp)
  24. /* returns 0 if number is composite 1 if prime
  25.    2 if proved prime by trial division */
  26. {
  27.   int factored = 0, flag = 0;
  28.   long b, p, r;
  29.   verylong za = 0, zs = 0, zn1 = 0;

  30.   *lmSize = *lpSize = 0;
  31.   zsadd(zn, - 1l, znm);
  32.   zsadd(zn, + 1l, znp);
  33.   zcopy(*znm, zrm);
  34.   zcopy(*znp, zrp);
  35.   zcopy(*znp, &zn1);
  36.   zpstart2();
  37.   p = zpnext();
  38.   zsqrt(zn, &zs, &za);
  39.   if (zscompare(zs, bound) > 0)
  40.     b = bound;
  41.   else {
  42.     flag = 1;
  43.     b = ztoint(zs);
  44.   }
  45.   while (!factored && p <= b) {
  46.     r = zsmod(*znp, p);
  47.     factored = r == 1;
  48.     if (!factored) {
  49.       if (r == 0) {
  50.         do {
  51.           zsdiv(*zrp, p, &za);
  52.           zcopy(za, zrp);
  53.         } while (zsmod(*zrp, p) == 0);
  54.         lp[*lpSize] = p;
  55.         *lpSize = *lpSize + 1;
  56.       }
  57.       if (r == 2) {
  58.         do {
  59.           zsdiv(*zrm, p, &za);
  60.           zcopy(za, zrm);
  61.         } while (zsmod(*zrm, p) == 0);
  62.         lm[*lmSize] = p;
  63.         *lmSize = *lmSize + 1;
  64.       }
  65.     }
  66.     p = zpnext();
  67.   }
  68.   zdiv(*znm, *zrm, zfm, &za);
  69.   zdiv(*znp, *zrp, zfp, &za);
  70.   zfree(&za);
  71.   zfree(&zs);
  72.   zfree(&zn1);
  73.   if (!factored && flag && p > b) factored = 2;
  74.   else factored = !factored;
  75.   return factored;
  76. }

  77. void ring_mul(long a, long r, long u,
  78.               verylong zn,
  79.               verylong *zx, verylong *zy,
  80.               verylong *zz)
  81. {
  82.   verylong za = 0, zb = 0, zc = 0;
  83.   verylong zp0 = 0, zp1 = 0, zs0 = 0, zs1 = 0;

  84.   zmulmod(zx[0], zy[0], zn, &zp0);
  85.   zmulmod(zx[1], zy[1], zn, &zp1);
  86.   zaddmod(zx[0], zx[1], zn, &zs0);
  87.   zaddmod(zy[0], zy[1], zn, &zs1);
  88.   if (r == 1) {
  89.     zsmulmod(zp1, a, zn, &za);
  90.     zaddmod(zp0, za, zn, &zz[0]);
  91.     zmulmod(zs0, zs1, zn, &za);
  92.     zsubmod(za, zp0, zn, &zb);
  93.     zsubmod(zb, zp1, zn, &zz[1]);
  94.   }
  95.   else if (r == 3) {
  96.     zaddmod(zp0, zp1, zn, &zz[0]);
  97.     zsmulmod(zp1, u - 1, zn, &za);
  98.     zmulmod(zs0, zs1, zn, &zb);
  99.     zaddmod(zb, za, zn, &zc);
  100.     zsubmod(zc, zp0, zn, &zz[1]);
  101.   }
  102.   zfree(&za);
  103.   zfree(&zb);
  104.   zfree(&zc);
  105.   zfree(&zp0);
  106.   zfree(&zp1);
  107.   zfree(&zs0);
  108.   zfree(&zs1);
  109. }

  110. void ring_sqr(long u, verylong zn,
  111.               verylong *zx, verylong *zz)
  112. {
  113.   verylong za = 0, zb = 0, zs = 0;

  114.   zsmulmod(zx[1], u, zn, &za);
  115.   zsmulmod(zx[0], 2l, zn, &zb);
  116.   zaddmod(za, zb, zn, &zs);
  117.   zmulmod(zx[0], zs, zn, &za);
  118.   zsadd(za, - 1l, &zb);
  119.   zmod(zb, zn, &zz[0]);
  120.   zmulmod(zx[1], zs, zn, &zz[1]);
  121.   zfree(&za);
  122.   zfree(&zb);
  123.   zfree(&zs);
  124. }

  125. void ring_pow(long a, long u,
  126.               verylong ze,
  127.               verylong zn,
  128.               verylong *zx,
  129.               verylong *zz)
  130. /* calculates z = x ^ e in the ring
  131.    (Z / nZ)[T]/(T ^ 2 - u * T - 1) */
  132. {
  133.   long i, r = zsmod(zn, 4l);
  134.   verylong za = 0, zb = 0;
  135.   verylong zA[2], zS[2], zT[2];

  136.   zA[0] = zA[1] = zS[0] = zS[1] = zT[0] = zT[1] = 0;
  137.   zcopy(ze, &za);
  138.   zzero(&zA[1]);
  139.   zone(&zA[0]);
  140.   zcopy(zx[0], &zS[0]);
  141.   zcopy(zx[1], &zS[1]);
  142.   while (zscompare(za, 0l) != 0) {
  143.     if (zodd(za)) {
  144.       ring_mul(a, r, u, zn, zA, zS, zz);
  145.       zcopy(zz[0], &zA[0]);
  146.       zcopy(zz[1], &zA[1]);
  147.     }
  148.     zrshift(za, 1l, &zb);
  149.     zcopy(zb, &za);
  150.     if (zscompare(za, 0l) != 0) {
  151.       ring_sqr(u, zn, zS, zT);
  152.       zcopy(zT[0], &zS[0]);
  153.       zcopy(zT[1], &zS[1]);
  154.     }
  155.   }
  156.   zfree(&za);
  157.   zfree(&zb);
  158.   for (i = 0; i < 2; i++) {
  159.     zfree(&zA[i]);
  160.     zfree(&zS[i]);
  161.     zfree(&zT[i]);
  162.   }
  163. }

  164. int test_for_nm(int *flag,
  165.                 verylong zn,
  166.                 verylong znm,
  167.                 verylong zp,
  168.                 verylong *zprod,
  169.                 verylong **zbeta)
  170. /* returns - 1 if test fails, 0 if n is composite,
  171.    1 otherwise */
  172. {
  173.   int found = 0, value;
  174.   long i, l, p, q, x;
  175.   verylong za = 0, zb = 0, zo = 0, zx = 0;

  176.   zpstart2();
  177.   for (i = 0; !found && i < 50; i++) {
  178.     x = zpnext();
  179.     zdiv(znm, zp, &za, &zb);
  180.     zintoz(x, &zx);
  181.     zexpmod(zx, za, zn, &zb);
  182.     found = zscompare(zb, 1l) != 0;
  183.   }
  184.   if (found) {
  185.     zexpmod(zx, znm, zn, &za);
  186.     value = zscompare(za, 1l) == 0;
  187.     if (value) {
  188.       zcopy(*zprod, &zo);
  189.       zsadd(zb, - 1l, &za);
  190.       zmulmod(*zprod, za, zn, &zb);
  191.       zcopy(zb, zprod);
  192.       value = zscompare(*zprod, 0l) == 0;
  193.       if (value) {
  194.         zgcd(zo, zn, &za);
  195.         printf("factor = ");  zwriteln(za);
  196.         value = 0;
  197.       }
  198.       else if (zprobprime(zp, 5l)) {
  199.         zpstart();
  200.         l = 1;
  201.         p = ztoint(zp);
  202.         do {
  203.           q = pow(p, l);
  204.           if (t % q == 0) {
  205.             flag[q] = 1;
  206.             for (i = 0; i < q - 1; i++) {
  207.               zsmul(znm, i, &za);
  208.               zsdiv(za, q, &zb);
  209.               zexpmod(zx, zb, zn, &zbeta[q][i]);
  210.             }
  211.           }
  212.           l++;
  213.         } while (q < t);
  214.         value = 1;
  215.       }
  216.       else value = 1;
  217.     }
  218.   }
  219.   else value = - 1;
  220.   if (!value) printf("composite by n - 1 test\n");
  221.   zfree(&za);
  222.   zfree(&zb);
  223.   zfree(&zo);
  224.   zfree(&zx);
  225.   return value;
  226. }

  227. int test_for_np(long a, long u,
  228.                 verylong zn,
  229.                 verylong znp,
  230.                 verylong zp,
  231.                 verylong *zprod)
  232. /* returns
  233.   - 1 if test fails, 0 if n is composite,
  234.   + 1 otherwise */
  235. {
  236.   int factored = 0, found = 0, value;
  237.   long d, m;
  238.   verylong za = 0, zd = 0, ze = 0, zi = 0;
  239.   verylong zx[2], zz[2];

  240.   zx[0] = zx[1] = zz[0] = zz[1] = 0;
  241.   zdiv(znp, zp, &ze, &za);
  242.   for (m = 1; !factored && !found && m <= 50; m++) {
  243.     d = m * (m + u) - a;
  244.     zintoz(d, &zd);
  245.     zinvmod(zd, zn, &zi);
  246.     factored = zscompare(zi, 0l) == 0;
  247.     if (!factored) {
  248.       zintoz(m * m + a, &za);
  249.       zmulmod(za, zi, zn, &zx[0]);
  250.       zintoz((2 * m + u) * a, &za);
  251.       zmulmod(za, zi, zn, &zx[1]);
  252.       ring_pow(a, u, ze, zn, zx, zz);
  253.       found = zscompare(zz[0], 1l) != 0 ||
  254.               zscompare(zz[1], 0l) != 0;
  255.     }
  256.   }
  257.   if (!factored && found) {
  258.     ring_pow(a, u, znp, zn, zx, zz);
  259.     factored = zscompare(zz[0], 1l) == 1 &&
  260.                zscompare(zz[1], 0l) == 0;
  261.     if (!factored) {
  262.       if (zscompare(zx[0], 0l) != 0)
  263.         zmulmod(*zprod, zx[0], zn, &za);
  264.       else
  265.         zmulmod(*zprod, zx[1], zn, &za);
  266.       factored = zscompare(za, 0l) == 0;
  267.       if (factored) {
  268.         zgcd(*zprod, zn, &za);
  269.         printf("factor: ");
  270.         zwriteln(za);
  271.       }
  272.       else zcopy(za, zprod);
  273.       if (factored) value = 0; else value = 1;
  274.     }
  275.   }
  276.   else if (factored) value = 0;
  277.   else value = - 1;
  278.   zfree(&za);
  279.   zfree(&zd);
  280.   zfree(&ze);
  281.   zfree(&zi);
  282.   zfree(&zx[0]);
  283.   zfree(&zx[1]);
  284.   zfree(&zz[0]);
  285.   zfree(&zz[1]);
  286.   if (!value) printf("composite by n + 1 test\n");
  287.   return value;
  288. }

  289. void norm(long a, long u, verylong zn,
  290.           verylong *znorm, verylong *zx)
  291. {
  292.   verylong za = 0, zb = 0, zc = 0;

  293.   zmulmod(zx[0], zx[0], zn, &za);
  294.   zmulmod(zx[0], zx[1], zn, &zb);
  295.   zsmulmod(zb, u, zn, &zc);
  296.   zaddmod(za, zc, zn, &zb);
  297.   zmulmod(zx[1], zx[1], zn, &za);
  298.   zsmulmod(za, - a, zn, &zc);
  299.   zaddmod(zb, zc, zn, znorm);
  300.   zfree(&za);
  301.   zfree(&zb);
  302.   zfree(&zc);
  303. }

  304. int Lucas_Lehmer(int *flag, long bound, long lmSize,
  305.                  long *lm, long lpSize, long *lp,
  306.                  verylong zn,
  307.                  verylong zfm, verylong zfp,
  308.                  verylong znm, verylong znp,
  309.                  verylong zrm, verylong zrp,
  310.                  verylong **zbeta)
  311. /* returns
  312.   - 4 could not find suitable a,
  313.   - 3 could not find suitable u,
  314.   - 2 if n - 1 test fails,
  315.   - 1 n + 1 test fails, 0 if n is composite,
  316.   + 1 if passed  */
  317. {
  318.   int f4_1, factored = 0, found = 0, test = 1;
  319.   long a, d, i, l, m, p, r, u;
  320.   verylong za = 0, zd = 0, ze = 0, zi = 0, zm = 0;
  321.   verylong zp = 0, zu = 0, zprod = 0, zx[2], zz[2];

  322.   zx[0] = zx[1] = zz[0] = zz[1] = 0;
  323.   zone(&zprod);
  324.   for (i = 0; test && i < lmSize; i++) {
  325.     p = lm[i];
  326.     zintoz(p, &zp);
  327.     test = test_for_nm(flag, zn, znm, zp, &zprod, zbeta);
  328.   }
  329.   if (test == 1) {
  330.     if (zcompare(zfm, zfp) > 0) zcopy(zfm, &za);
  331.     else zcopy(zfp, &za);
  332.     zmul(za, zfm, &zd);
  333.     zmul(zd, zfp, &ze);
  334.     zintoz(bound, &za);
  335.     zsexp(za, 3l, &zm);
  336.     zmul(ze, zm, &za);
  337.     f4_1 = zcompare(zn, za) < 0;
  338.     if (f4_1 && zscompare(zrm, 1l) != 0)
  339.       test = test_for_nm(flag, zn, znm, zrm, &zprod, zbeta);
  340.   }
  341.   if (test == 1) {
  342.     r = zsmod(zn, 4l);
  343.     if (r == 1) {
  344.       zrshift(znm, 1l, &ze);
  345.       zpstart2();
  346.       for (i = 1; !found && i <= 50; i++) {
  347.         a = zpnext();
  348.         zintoz(a, &za);
  349.         zexpmod(za, ze, zn, &zm);
  350.         found = zcompare(zm, znm) == 0;
  351.       }
  352.       if (!found) test = - 4;
  353.       else {
  354.         l = 1;
  355.         do {
  356.           p = pow(2, l);
  357.           zintoz(a, &za);
  358.           if (t % p == 0 && flag[p]) {
  359.             for (i = 0; i < p; i++) {
  360.               zsmul(znm, i, &zd);
  361.               zsdiv(zd, p, &ze);
  362.               zexpmod(za, ze, zn, &zbeta[p][i]);
  363.             }
  364.           }
  365.           l++;
  366.         } while (p < sqrt(t));
  367.       }
  368.     }
  369.     else {
  370.       a = 1;
  371.       for (i = 1; !found && i <= 50; i++) {
  372.         zintoz(i * i + 4l, &zu);
  373.         found = zjacobi(zu, zn) == - 1;
  374.         if (found) u = i;
  375.       }
  376.       if (!found) test = - 3;
  377.       else {
  378.         found = 0;
  379.         for (m = 1; !factored && !found && m <= 50; m++) {
  380.           d = m * (m + u) - a;
  381.           zintoz(d, &zd);
  382.           zinvmod(zd, zn, &zi);
  383.           factored = zscompare(zi, 0l) == 0;
  384.           if (!factored) {
  385.             found = 1;
  386.             zintoz(m * m + a, &za);
  387.             zmulmod(za, zi, zn, &zx[0]);
  388.             zintoz((2 * m + u) * a, &za);
  389.             zmulmod(za, zi, zn, &zx[1]);
  390.           }
  391.         }
  392.         if (!factored && !found) test = - 2;
  393.         else if (found) {
  394.           zone(&zx[0]);
  395.           zintoz(u, &zx[1]);
  396.           zrshift(znp, 1l, &ze);
  397.           ring_pow(a, u, ze, zn, zx, zz);
  398.           test = zcompare(zz[0], znm) == 0 &&
  399.                  zscompare(zz[1], 0l) == 0;
  400.         }
  401.         else test = 0;
  402.       }
  403.     }
  404.   }
  405.   else if (test == - 1) test = - 2;
  406.   if (test == 1) {
  407.     for (i = 0; test && i < lpSize; i++) {
  408.       zintoz(lp[i], &zp);
  409.       test = test_for_np(a, u, zn, znp, zp, &zprod);
  410.     }
  411.     if (test == 1) {
  412.       if (f4_1) {
  413.         if (zscompare(zrp, 1l) == 0) test = 2;
  414.         else  {
  415.           test = test_for_np(a, u, zn, znp, zrp, &zprod);
  416.           if (test) test = 2;
  417.         }
  418.       }
  419.     }
  420.   }
  421.   if (test == 1) {
  422.     zgcd(zprod, zn, &zd);
  423.     test = zscompare(zd, 1l) == 0;
  424.   }
  425.   zfree(&za);
  426.   zfree(&zd);
  427.   zfree(&ze);
  428.   zfree(&zi);
  429.   zfree(&zm);
  430.   zfree(&zp);
  431.   zfree(&zu);
  432.   zfree(&zprod);
  433.   zfree(&zx[0]);
  434.   zfree(&zx[1]);
  435.   zfree(&zz[0]);
  436.   zfree(&zz[1]);
  437.   return test;
  438. }

  439. int main(void)
  440. {
  441.   char answer[256];
  442.   int flag[256], td;
  443.   long cols, rows;
  444.   long lm[256], lp[256], lmSize, lpSize;
  445.   long i, j, l, n = 0, p, q, r[32], tt;
  446.   verylong zn = 0;
  447.   verylong zfm = 0, zfp = 0, znm = 0, znp = 0;
  448.   verylong zrm = 0, zrp = 0;
  449.   verylong **zbeta;

  450.   zpstart2();
  451.   do {
  452.     p = zpnext();
  453.     if (t % p == 0) {
  454.       r[n++] = p;
  455.       l = 2;
  456.       do {
  457.         q = pow(p, l);
  458.         if (t % q == 0) r[n++] = q;
  459.         l++;
  460.       } while (q < sqrt(t));
  461.     }
  462.   } while (p < sqrt(t));
  463.   for (i = 0; i < n - 1; i++)
  464.     for (j = i + 1; j < n; j++)
  465.       if (r[i] > r[j])
  466.         tt = r[i], r[i] = r[j], r[j] = tt;
  467.   cols = rows = r[n - 1] + 1;
  468.   zbeta = calloc(rows, sizeof(verylong *));
  469.   if (!zbeta) {
  470.     fprintf(stderr, "fatal error\ninsufficient memory\n");
  471.     exit(1);
  472.   }
  473.   for (i = 0; i < rows; i++) {
  474.     zbeta[i] = calloc(cols, sizeof(verylong));
  475.     if (!zbeta[i]) {
  476.       fprintf(stderr, "fatal error\ninsufficient memory\n");
  477.       exit(1);
  478.     }
  479.   }
  480.   do {
  481.     printf("enter the number to be tested below:\n");
  482.     zread(&zn);
  483.     zwriteln(zn);
  484.     if (zprobprime(zn, 5l)) {
  485.       td = trial_division(BOUND, zn, lm, &lmSize,
  486.                          lp, &lpSize,  &zfm, &zfp, &znp,
  487.                          &znm, &zrm, &zrp);
  488.       if (td == 1) {
  489.         for (i = 0; i < 256; i++) flag[i] = 0;
  490.         switch (Lucas_Lehmer(flag, BOUND, lmSize,
  491.                              lm, lpSize, lp, zn,
  492.                              zfm, zfp, znm, znp,
  493.                              zrm, zrp, zbeta)) {
  494.           case - 4 :
  495.             printf("failed could not find suitable a\n");
  496.             break;
  497.           case - 3 :
  498.             printf("failed could not find suitable u\n");
  499.             break;
  500.           case - 2 :
  501.             printf("Lucas-Lehmer n - 1 test failed\n");
  502.             break;
  503.           case - 1 :
  504.             printf("Lucas-Lehmer n + 1 test failed\n");
  505.             break;
  506.           case + 0 :
  507.             break;
  508.           case + 1 :
  509.             printf("number passed Lucas-Lehmer test\n");
  510.             break;
  511.           case + 2 :
  512.             printf("number proven prime by Lucas-Lehmer test\n");
  513.             break;
  514.         }
  515.       }
  516.       else if (!td)
  517.         printf("number composite by trial division\n");
  518.       else
  519.         printf("number proven prime by trial division\n");
  520.     }
  521.     else printf("number composite by Miller-Rabin\n");
  522.     printf("another number (n or y) ? ");
  523.     scanf("%s", answer);
  524.   } while (tolower(answer[0]) == 'y');
  525.   zfree(&zn);
  526.   zfree(&zfm);
  527.   zfree(&zfp);
  528.   zfree(&znm);
  529.   zfree(&znp);
  530.   zfree(&zrm);
  531.   zfree(&zrp);
  532.   for (i = 0; i < rows; i++) {
  533.     for (j = 0; j < cols; j++)
  534.       zfree(&zbeta[i][j]);
  535.     free(zbeta[i]);
  536.   }
  537.   free(zbeta);
  538.   return 0;
  539. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-11-30 21:47:47 | 显示全部楼层

  1. *
  2.   Author:  Pate Williams (c) 1997

  3.   Aldleman-Pomerance-Rumely-Cohen-Lenstra primality
  4.   test. See "Implementation of a New Primality Test",
  5.   Mathematics of Computation, Volume 48, Number 177,
  6.   January 1987, pages 103 - 121 by H. Cohen and
  7.   A. K. Lenstra. Table generation.
  8. */

  9. #include <limits.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include "lip.h"

  13. #define t 25200l

  14. struct power {long x, p;};
  15. struct long_factor {long expon, prime;};
  16. struct very_factor {int expon; verylong prime;};

  17. void long_trial_division(long bound, verylong zn,
  18.                          struct long_factor *f,
  19.                          long *count)
  20. {
  21.   int one = 0, pri = 0, value;
  22.   long e, p;
  23.   verylong za = 0, zb = 0;

  24.   *count = 0;
  25.   zcopy(zn, &za);
  26.   zpstart2();
  27.   do {
  28.     p = zpnext();
  29.     if (zsmod(za, p) == 0) {
  30.       e = 0;
  31.       do {
  32.         e++;
  33.         zsdiv(za, p, &zb);
  34.         zcopy(zb, &za);
  35.       } while (zsmod(za, p) == 0);
  36.       f[*count].expon = e;
  37.       f[*count].prime = p;
  38.       *count = *count + 1;
  39.       one = zscompare(za, 1l) == 0;
  40.       if (!one) pri = zprobprime(za, 5l);
  41.     }
  42.   } while (!one && !pri && p <= bound);
  43.   if (pri) {
  44.     f[*count].expon = 1;
  45.     f[*count].prime = ztoint(za);
  46.     *count = *count + 1;
  47.     value = zscompare(za, LONG_MAX) > 0;
  48.   }
  49.   if (value || p > bound) {
  50.     fprintf(stderr, "fatal error\ncan't factor number");
  51.     exit(1);
  52.   }
  53.   zfree(&za);
  54.   zfree(&zb);
  55. }

  56. void compute_e_of_t(verylong zt, long *Q,
  57.                     verylong *ze, long *Q_count)
  58. {
  59.   int found;
  60.   long e, i, lf_count, p, q;
  61.   struct long_factor lf[16];
  62.   verylong zq = 0, zr = 0;

  63.   *Q_count = 0;
  64.   long_trial_division(1000000l, zt, lf, &lf_count);
  65.   printf("t = "); zwriteln(zt);
  66.   printf("prime factorization of t\n");
  67.   for (i = 0; i < lf_count; i++) {
  68.     printf("%2ld", lf[i].prime);
  69.     if (lf[i].expon == 1) printf("\n");
  70.     else printf(" ^ %ld\n", lf[i].expon);
  71.   }
  72.   zintoz(2l, ze);
  73.   zpstart2();
  74.   do {
  75.     p = zpnext();
  76.     q = p - 1;
  77.     if (zsmod(zt, q) == 0) {
  78.       Q[*Q_count] = p;
  79.       *Q_count = *Q_count + 1;
  80.       e = 1;
  81.       found = 0;
  82.       for (i = 0; !found && i < lf_count; i++) {
  83.         if (p == lf[i].prime) {
  84.           found = 1;
  85.           e += lf[i].expon;
  86.         }
  87.       }
  88.       zintoz(p, &zq);
  89.       zsexp(zq, e, &zr);
  90.       zmul(*ze, zr, &zq);
  91.       zcopy(zq, ze);
  92.     }
  93.   } while (zscompare(zt, q) >= 0);
  94.   zfree(&zq);
  95.   zfree(&zr);
  96. }

  97. void very_trial_division(long bound, verylong zn,
  98.                          struct very_factor *f,
  99.                          long *count)
  100. {
  101.   int e, one = 0, pri = 0;
  102.   long p;
  103.   verylong za = 0, zb = 0;

  104.   *count = 0;
  105.   zcopy(zn, &za);
  106.   zpstart2();
  107.   do {
  108.     p = zpnext();
  109.     if (zsmod(za, p) == 0) {
  110.       e = 0;
  111.       do {
  112.         e++;
  113.         zsdiv(za, p, &zb);
  114.         zcopy(zb, &za);
  115.       } while (zsmod(za, p) == 0);
  116.       f[*count].expon = e;
  117.       zintoz(p, &f[*count].prime);
  118.       *count = *count + 1;
  119.       one = zscompare(za, 1l) == 0;
  120.       if (!one) pri = zprobprime(za, 5l);
  121.     }
  122.   } while (!one && !pri && p <= bound);
  123.   if (pri) {
  124.     f[*count].expon = 1;
  125.     zcopy(za, &f[*count].prime);
  126.     *count = *count + 1;
  127.   }
  128.   if (p > bound) {
  129.     fprintf(stderr, "fatal error\ncan't factor number");
  130.     exit(1);
  131.   }
  132.   zfree(&za);
  133.   zfree(&zb);
  134. }

  135. void primitive_root(verylong zp, verylong *za)
  136. {
  137.   long i, k;
  138.   struct very_factor f[16];
  139.   verylong zb = 0, ze = 0, zq = 0, zr = 0, zp1 = 0;

  140.   for (i = 0; i < 16; i++) f[i].prime = 0;
  141.   zsadd(zp, - 1l, &zp1);
  142.   very_trial_division(1000000l, zp1, f, &k);
  143.   zone(za);
  144.   L2:
  145.   i = 0;
  146.   zsadd(*za, 1l, &zb);
  147.   zcopy(zb, za);
  148.   L3:
  149.   zdiv(zp1, f[i].prime, &zq, &zr);
  150.   zexpmod(*za, zq, zp, &ze);
  151.   if (zscompare(ze, 1l) == 0) goto L2;
  152.   if (++i < k) goto L3;
  153.   zfree(&zb);
  154.   zfree(&ze);
  155.   zfree(&zq);
  156.   zfree(&zr);
  157.   zfree(&zp1);
  158.   for (i = 0; i < 16; i++) zfree(&f[i].prime);
  159. }

  160. int fcmp(const void *g1, const void *g2)
  161. {
  162.   struct power *p1 = (struct power *) g1;
  163.   struct power *p2 = (struct power *) g2;

  164.   if (p1->p < p2->p) return - 1;
  165.   if (p1->p > p2->p) return + 1;
  166.   return 0;
  167. }

  168. void build_f_table(long q, verylong zg, verylong zq, FILE *file)
  169. {
  170.   long f, q1 = q - 1, q2 = q - 2, x;
  171.   long *h = calloc(q, sizeof(long));
  172.   struct power *g, key, *ptr;
  173.   verylong zr = 0, zs = 0, zt = 0;

  174.   g = calloc(q, sizeof(struct power));
  175.   if (!g || !h) {
  176.     fprintf(stderr, "fatal error\ninsufficient memory\n");
  177.     exit(1);
  178.   }
  179.   zone(&zr);
  180.   g[0].x = 0;
  181.   g[0].p = 1;
  182.   for (x = 1; x <= q2; x++) {
  183.     zsexpmod(zg, x, zq, &zs);
  184.     zsubmod(zr, zs, zq, &zt);
  185.     g[x].x = x;
  186.     g[x].p = ztoint(zs);
  187.     h[x] = ztoint(zt);
  188.   }
  189.   qsort(g, q1, sizeof(struct power), fcmp);
  190.   fwrite(&q, sizeof(q), 1, file);
  191.   for (x = 1; x <= q2; x++) {
  192.     key.x = x;
  193.     key.p = h[x];
  194.     ptr = bsearch(&key, g, q1, sizeof(struct power), fcmp);
  195.     if (!ptr) {
  196.       fprintf(stderr, "fatal error\ncan't find logarith\n");
  197.       exit(1);
  198.     }
  199.     f = ptr->x;
  200.     fwrite(&f, sizeof(f), 1, file);
  201.   }
  202.   free(g);
  203.   free(h);
  204.   zfree(&zr);
  205.   zfree(&zs);
  206.   zfree(&zt);
  207. }

  208. void generate_f_table(long q_count, long *q)
  209. {
  210.   long i, i0, p;
  211.   FILE *file = fopen("f_table.dat", "w+b");
  212.   verylong zg = 0, zp = 0;

  213.   if (!file) {
  214.     fprintf(stderr, "fatal error\ncan't open file\n");
  215.     exit(1);
  216.   }
  217.   if (q[0] == 2) i0 = 1; else i0 = 0;
  218.   for (i = i0; i < q_count; i++) {
  219.     printf("\b\b%ld", i);
  220.     p = q[i];
  221.     zintoz(p, &zp);
  222.     primitive_root(zp, &zg);
  223.     build_f_table(p, zg, zp, file);
  224.   }
  225.   zfree(&zg);
  226.   zfree(&zp);
  227.   fclose(file);
  228. }

  229. void generate_j_table(long q_count, long q0)
  230. {
  231.   long A, B, *a, *f, i, k, l, m, p, pk;
  232.   long pk1, pk3, q, q1, r, r0, x;
  233.   FILE *f_file = fopen("f_table.dat", "r+b");
  234.   FILE *j_file = fopen("j_table.dat", "w+b");

  235.   if (!f_file || !j_file) {
  236.     fprintf(stderr, "fatal error\ncan't open file(s)\n");
  237.     exit(1);
  238.   }
  239.   if (q0 == 2) r0 = 1; else r0 = 0;
  240.   for (r = r0; r < q_count; r++) {
  241.     printf("\b\b%ld", r);
  242.     fread(&q, sizeof(q), 1, f_file);
  243.     f = calloc(q, sizeof(long));
  244.     if (!f) {
  245.       fprintf(stderr, "fatal error\ninsufficient memory\n");
  246.       exit(1);
  247.     }
  248.     for (i = 1; i <= q - 2; i++)
  249.       fread(&f[i], sizeof(f[i]), 1, f_file);
  250.     q1 = q - 1;
  251.     zpstart2();
  252.     do {
  253.       p = zpnext();
  254.       if (q1 % p == 0) {
  255.         k = 0;
  256.         do {
  257.           k++;
  258.           q1 /= p;
  259.         } while (q1 % p == 0);
  260.       }
  261.       pk = pow(p, k);
  262.       pk1 = pow(p, k - 1);
  263.       m = (p - 1) * pk1;
  264.       a = calloc(m, sizeof(long));
  265.       if (!a) {
  266.         fprintf(stderr, "fatal error\ninsufficient memory\n");
  267.         exit(1);
  268.       }
  269.       if (pk != 2) {
  270.         for (i = 0; i < m; i++) a[i] = 0;
  271.         A = B = 1;
  272.         for (x = 1; x <= q - 2; x++) {
  273.           l = (A * x + B * f[x]) % pk;
  274.           if (l < m) a[l]++;
  275.           else
  276.             for (i = 1; i < p; i++)
  277.               a[((l - i) * pk1) % l]--;
  278.         }
  279.         fwrite(&m, sizeof(m), 1, j_file);
  280.         for (i = 0; i < m; i++)
  281.           fwrite(&a[i], sizeof(a[i]), 1, j_file);
  282.       }
  283.       else if (p == 2 && k >= 3) {
  284.         for (i = 0; i < m; i++) a[i] = 0;
  285.         A = 2, B = 1;
  286.         for (x = 1; x <= q - 2; x++) {
  287.           l = (A * x + B * f[x]) % pk;
  288.           if (l < m) a[l]++;
  289.           else
  290.             for (i = 1; i < p; i++)
  291.               a[((l - i) * pk1) % l]--;
  292.         }
  293.         fwrite(&m, sizeof(m), 1, j_file);
  294.         for (i = 0; i < m; i++)
  295.           fwrite(&a[i], sizeof(a[i]), 1, j_file);
  296.         for (i = 0; i < m; i++) a[i] = 0;
  297.         pk3 = pow(2, k - 3);
  298.         A = 3 * pk3, B = pk3;
  299.         for (x = 1; x <= q - 2; x++) {
  300.           l = (A * x + B * f[x]) % pk;
  301.           if (l < m) a[l]++;
  302.           else
  303.             for (i = 1; i < p; i++)
  304.               a[((l - i) * pk1) % l]--;
  305.         }
  306.         fwrite(&m, sizeof(m), 1, j_file);
  307.         for (i = 0; i < m; i++)
  308.           fwrite(&a[i], sizeof(a[i]), 1, j_file);
  309.       }
  310.       free(a);
  311.     } while (q1 != 1);
  312.   }
  313.   free(f);
  314.   fclose(f_file);
  315.   fclose(j_file);
  316. }

  317. int main(void)
  318. {
  319.   long q_count, q[64];
  320.   verylong ze = 0, zt = 0;

  321.   zintoz(t, &zt);
  322.   compute_e_of_t(zt, q, &ze, &q_count);
  323.   printf("e(t) = "); zwriteln(ze);
  324.   printf("log10(e(t)) = %lf\n", zln(ze) / log(10.0));
  325.   printf("number of q primes = %ld\n", q_count);
  326.   generate_f_table(q_count, q);
  327.   printf("\ngenerated f_table\n");
  328.   generate_j_table(q_count, q[0]);
  329.   printf("\ngenerated j_table\n");
  330.   zfree(&ze);
  331.   zfree(&zt);
  332.   return 0;
  333. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-11-30 21:49:49 | 显示全部楼层

  1. /*
  2.   Author:  Pate Williams (c) 1997

  3.   Algorithm 10.3.3 (Lenstra's ECM). See "A Course
  4.   in Computational Algebraic Number Theory" by
  5.   Henri Cohen page 488.
  6. */

  7. #include <ctype.h>
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include "lip.h"

  11. #define CURVES 50l

  12. struct point {verylong zx, zy, zz;};

  13. int partial_addition(verylong za,
  14.                      verylong zn,
  15.                      struct point P,
  16.                      struct point Q,
  17.                      struct point *R,
  18.                      verylong *zd)
  19. /* returns 0 if sum is found or 1 if divisor is found */
  20. {
  21.   int value = 0;
  22.   verylong zb = 0, zc = 0, zl = 0, zs = 0, zt = 0;
  23.   verylong zx = 0, zy = 0, zy2 = 0;

  24.   if (zcompare(P.zx, Q.zx) == 0 &&
  25.       zscompare(P.zy, 0l) == 0 &&
  26.       zscompare(Q.zy, 0l) == 0) {
  27.     zzero(&R->zx);
  28.     zone(&R->zy);
  29.     return 0;
  30.   }
  31.   zsub(zn, Q.zy, &zb);
  32.   if (zcompare(P.zx, Q.zx) == 0 &&
  33.       zcompare(P.zy, zb) == 0) {
  34.     zzero(&R->zx);
  35.     zone(&R->zy);
  36.     zfree(&zb);
  37.     return 0;
  38.   }
  39.   if (zscompare(P.zx, 0l) == 0 &&
  40.       zscompare(P.zy, 1l) == 0 &&
  41.       zscompare(P.zz, 0l) == 0) {
  42.     /* O + Q = Q */
  43.     zcopy(Q.zx, &R->zx);
  44.     zcopy(Q.zy, &R->zy);
  45.     zcopy(Q.zz, &R->zz);
  46.     value = 0;
  47.   }
  48.   else if (zscompare(Q.zx, 0l) == 0 &&
  49.            zscompare(Q.zy, 1l) == 0 &&
  50.            zscompare(Q.zz, 0l) == 0) {
  51.     /* P + O = P */
  52.     zcopy(P.zx, &R->zx);
  53.     zcopy(P.zy, &R->zy);
  54.     zcopy(P.zz, &R->zz);
  55.     value = 0;
  56.   }
  57.   else {
  58.     /* P != O and Q != O */
  59.     zcopy(Q.zy, &zy2);
  60.     znegate(&zy2);
  61.     if (zcompare(P.zx, Q.zx) == 0  &&
  62.         zcompare(P.zy, zy2)  == 0) {
  63.       zzero(&R->zx);
  64.       zone(&R->zy);
  65.       zzero(&R->zz);
  66.     }
  67.     else {
  68.       if (zcompare(P.zx, Q.zx) != 0) {
  69.         zsubmod(P.zx, Q.zx, zn, &zx);
  70.         zexteucl(zx, &zs, zn, &zt, zd);
  71.         if (zscompare(*zd, 1l) != 0) goto L1;
  72.         zsubmod(P.zy, Q.zy, zn, &zy);
  73.         zmulmod(zs, zy, zn, &zl);
  74.       }
  75.       else {
  76.         zaddmod(P.zy, Q.zy, zn, &zy);
  77.         zexteucl(zy, &zs, zn, &zt, zd);
  78.         if (zscompare(*zd, 1l) != 0) goto L1;
  79.         zmulmod(P.zx, P.zx, zn, &zb);
  80.         zsmulmod(zb, 3l, zn, &zc);
  81.         zaddmod(zc, za, zn, &zb);
  82.         zmulmod(zs, zb, zn, &zl);
  83.       }
  84.       zmulmod(zl, zl, zn, &zb);
  85.       zaddmod(P.zx, Q.zx, zn, &zc);
  86.       zsubmod(zb, zc, zn, &zx);
  87.       zcopy(zx, &R->zx);
  88.       zsubmod(zx, P.zx, zn, &zb);
  89.       zmulmod(zl, zb, zn, &zc);
  90.       zaddmod(zc, P.zy, zn, &zy);
  91.       znegate(&zy);
  92.       zcopy(zy, &R->zy);
  93.       zone(&R->zz);
  94.       goto L2;
  95.       L1:
  96.       value = 1;
  97.       L2:
  98.     }
  99.   }
  100.   zfree(&zb);
  101.   zfree(&zc);
  102.   zfree(&zl);
  103.   zfree(&zs);
  104.   zfree(&zt);
  105.   zfree(&zx);
  106.   zfree(&zy);
  107.   return value;
  108. }

  109. int multiply(long k,
  110.              verylong za,
  111.              verylong zn,
  112.              struct point P,
  113.              struct point *R,
  114.              verylong *zd)
  115. {
  116.   int value = 0;
  117.   struct point A, S, T;

  118.   A.zx = A.zy = A.zz = S.zx = S.zy = S.zz = 0;
  119.   T.zx = T.zy = T.zz = 0;
  120.   zzero(&R->zx);
  121.   zone(&R->zy);
  122.   zzero(&R->zz);
  123.   zcopy(P.zx, &S.zx);
  124.   zcopy(P.zy, &S.zy);
  125.   zcopy(P.zz, &S.zz);
  126.   while (!value && k != 0) {
  127.     if (k & 1) {
  128.       value = partial_addition(za, zn, *R, S, &A, zd);
  129.       zcopy(A.zx, &R->zx);
  130.       zcopy(A.zy, &R->zy);
  131.       zcopy(A.zz, &R->zz);
  132.     }
  133.     k >>= 1;
  134.     if (!value && k != 0) {
  135.       value = partial_addition(za, zn, S, S, &T, zd);
  136.       zcopy(T.zx, &S.zx);
  137.       zcopy(T.zy, &S.zy);
  138.       zcopy(T.zz, &S.zz);
  139.     }
  140.   }
  141.   if (zscompare(R->zy, 0l) < 0) {
  142.     zadd(R->zy, zn, &A.zy);
  143.     zcopy(A.zy, &R->zy);
  144.   }
  145.   zfree(&A.zx);
  146.   zfree(&A.zy);
  147.   zfree(&A.zz);
  148.   zfree(&S.zx);
  149.   zfree(&S.zy);
  150.   zfree(&S.zz);
  151.   zfree(&T.zx);
  152.   zfree(&T.zy);
  153.   zfree(&T.zz);
  154.   return value;
  155. }

  156. int LenstrasECM(verylong *zN, verylong *zg)
  157. {
  158.   int expon = 0, found;
  159.   long B = 2000000l, i, j, k = 0, l, *p, q, q1;
  160.   struct point x, y;
  161.   verylong za[CURVES], zb = 0, zd = 0;

  162.   for (i = 0; i < CURVES; i++) za[i] = 0;
  163.   x.zx = x.zy = x.zz = y.zx = y.zy = y.zz = 0;
  164.   zpstart2();
  165.   do { q = zpnext(); k++; } while (q < B);
  166.   p = calloc(k, sizeof(long));
  167.   if (!p) {
  168.     fprintf(stderr, "fatal error\ninsufficient memory\n");
  169.     exit(1);
  170.   }
  171.   zpstart2();
  172.   for (i = 0; i < k; i++) p[i] = zpnext();
  173.   for (i = 0; i < CURVES; i++)
  174.     zrandomb(*zN, &za[i]);
  175.   L2:
  176.   zone(&x.zx);
  177.   zone(&x.zy);
  178.   zzero(&x.zz);
  179.   i = - 1;
  180.   L3:
  181.   i++;
  182.   if (i == k) {
  183.     for (i = 0; i < CURVES; i++)
  184.       zrandomb(*zN, &za[i]);
  185.     goto L2;
  186.   }
  187.   q = p[i];
  188.   q1 = q;
  189.   l = B / q;
  190.   while (q1 <= l) q1 *= q;
  191.   found = 0;
  192.   for (j = 0; !found && j < CURVES; j++)
  193.     found = multiply(q1, za[j], *zN, x, &y, &zd);
  194.   if (!found) goto L3;
  195.   zcopy(y.zx, &x.zx);
  196.   zcopy(y.zy, &x.zy);
  197.   zcopy(y.zz, &x.zz);
  198.   zgcd(zd, *zN, zg);
  199.   if (zcompare(*zg, *zN) == 0) {
  200.     for (j = 0; j < CURVES; j++)
  201.       zrandomb(*zN, &za[j]);
  202.     goto L2;
  203.   }
  204.   do {
  205.     zdiv(*zN, *zg, &zb, &zd);
  206.     zcopy(zb, zN);
  207.     zmod(*zN, *zg, &zd);
  208.     expon++;
  209.   } while (zscompare(zd, 0l) == 0);
  210.   for (i = 0; i < CURVES; i++) zfree(&za[i]);
  211.   zfree(&zb);
  212.   zfree(&zd);
  213.   zfree(&x.zx);
  214.   zfree(&x.zy);
  215.   zfree(&x.zz);
  216.   zfree(&y.zx);
  217.   zfree(&y.zy);
  218.   zfree(&y.zz);
  219.   return expon;
  220. }

  221. int main(void)
  222. {
  223.   int cant, expon, one, pri;
  224.   char answer[256];
  225.   verylong zN = 0, zd = 0, zg = 0;

  226.   do {
  227.     printf("enter the number to be factored below:\n");
  228.     zread(&zN);
  229.     if (zprobprime(zN, 5l))
  230.       printf("number is prime\n");
  231.     else {
  232.       printf("number is composite\n");
  233.       zintoz(6l, &zg);
  234.       zgcd(zN, zg, &zd);
  235.       if (zscompare(zd, 1l) != 0)
  236.         printf("number can't be factored using Lenstra's ECM\n");
  237.       else {
  238.         printf("factors:\n");
  239.         cant = 0, pri = 0;
  240.         do {
  241.           expon = LenstrasECM(&zN, &zg);
  242.           zwrite(zg);
  243.           if (expon == 1) printf("\n");
  244.           else printf(" ^ %d\n", expon);
  245.           one = zscompare(zN, 1l) == 0;
  246.           if (!one) pri = zprobprime(zN, 5l);
  247.           zintoz(6l, &zg);
  248.           zgcd(zN, zg, &zd);
  249.           if (zscompare(zd, 1l) != 0) {
  250.             printf("number can't be factored using Lenstra's ECM\n");
  251.             cant = 1;
  252.           }
  253.         } while (!cant && !one && !pri);
  254.         if (pri) zwriteln(zN);
  255.         if (cant) {
  256.           zwriteln(zN);
  257.           printf("last factor is composite\n");
  258.         }
  259.       }
  260.     }
  261.     printf("another number (n or y)? ");
  262.     scanf("%s", answer);
  263.   } while (tolower(answer[0]) == 'y');
  264.   zfree(&zN);
  265.   zfree(&zd);
  266.   zfree(&zg);
  267.   return 0;
  268. }
复制代码
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-11-30 21:54:49 | 显示全部楼层
需要freelip库

ftp://ftp.ox.ac.uk/pub/math/freelip/
要休息了
明天想办法下载下来这个库
就补全了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2008-12-1 11:56:44 | 显示全部楼层
斑竹果然是强人
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-12-1 17:14:08 | 显示全部楼层
http://cr.yp.to/arith.html
几个算法,没仔细看
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2008-12-1 17:20:29 | 显示全部楼层
http://topic.csdn.net/t/20011210/22/414003.html

freelip_1.1.tar.gz (197.02 KB, 下载次数: 18)
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-4-18 18:19:46 | 显示全部楼层
原帖由 无心人 于 2008-12-1 17:20 发表
http://topic.csdn.net/t/20011210/22/414003.html

602

我一直很诧异,为什么各位经常可以搞到这么多我看来这么离奇的地方的奇怪的东西?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2009-4-18 18:56:58 | 显示全部楼层
说是无心实乃有心人。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-2-13 12:20:28 | 显示全部楼层
我只能写VB的,对C还不会,就像上面的那两个几百行的程序,我把它复制下来,在C++6.0上却通不过编译器。
这两个程序在编译时都指出是#include "lip.h"这一行出了问题,通不过。而我又不知道这是为什么。烦啊。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-5-3 13:22 , Processed in 0.064907 second(s), 19 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表