pell_factorization_anynum.pl 1.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. #!/usr/bin/perl
  2. # Daniel "Trizen" Șuteu
  3. # Date: 03 February 2019
  4. # https://github.com/trizen
  5. # A simple integer factorization method, using square root convergents.
  6. # See also:
  7. # https://en.wikipedia.org/wiki/Pell%27s_equation
  8. use 5.020;
  9. use strict;
  10. use warnings;
  11. use ntheory qw(random_nbit_prime);
  12. use Math::AnyNum qw(:all);
  13. use experimental qw(signatures);
  14. sub pell_factorization ($n) {
  15. my $x = isqrt($n);
  16. my $y = $x;
  17. my $z = 1;
  18. my $r = 2 * $x;
  19. my $w = $r;
  20. return $x if is_square($n);
  21. my ($f1, $f2) = (1, $x);
  22. for (; ;) {
  23. $y = $r*$z - $y;
  24. $z = idiv($n - $y*$y, $z);
  25. $r = idiv($x + $y, $z);
  26. ($f1, $f2) = ($f2, ($r*$f2 + $f1) % $n);
  27. if (is_square($z)) {
  28. my $g = gcd($f1 - isqrt($z), $n);
  29. if ($g > 1 and $g < $n) {
  30. return $g;
  31. }
  32. }
  33. return $n if ($z == 1);
  34. }
  35. }
  36. for (1 .. 10) {
  37. my $n = random_nbit_prime(25) * random_nbit_prime(25);
  38. say "PellFactor($n) = ", pell_factorization($n);
  39. }
  40. __END__
  41. PellFactor(607859142082991) = 20432749
  42. PellFactor(926859728053057) = 33170069
  43. PellFactor(523709106944971) = 19544953
  44. PellFactor(379392152082407) = 18361823
  45. PellFactor(397926699623521) = 22529261
  46. PellFactor(596176048102421) = 27540133
  47. PellFactor(556290216898421) = 21828529
  48. PellFactor(799063586749279) = 27381929
  49. PellFactor(513015423767879) = 25622173
  50. PellFactor(964450431874939) = 30653317