#!/usr/bin/perl # Author: Daniel "Trizen" Șuteu # Date: 02 August 2020 # Edit: 07 January 2021 # https://github.com/trizen # A new factorization method for numbers that have all prime factors close to each other. # Inpsired by Fermat's Little Theorem (FLT). use 5.020; use warnings; use experimental qw(signatures); use Math::GMPz; sub FLT_find_factor ($n, $base = 2, $reps = 1e5) { $n = Math::GMPz->new("$n"); state $z = Math::GMPz::Rmpz_init_nobless(); state $t = Math::GMPz::Rmpz_init_nobless(); my $g = Math::GMPz::Rmpz_init(); Math::GMPz::Rmpz_set_ui($t, $base); Math::GMPz::Rmpz_set_ui($z, $base); Math::GMPz::Rmpz_powm($z, $z, $n, $n); # Cannot factor Fermat pseudoprimes if (Math::GMPz::Rmpz_cmp_ui($z, $base) == 0) { return undef; } my $multiplier = $base * $base; for (my $k = 1 ; $k <= $reps ; ++$k) { Math::GMPz::Rmpz_mul_ui($t, $t, $multiplier); Math::GMPz::Rmpz_mod($t, $t, $n) if ($k % 10 == 0); Math::GMPz::Rmpz_sub($g, $z, $t); Math::GMPz::Rmpz_gcd($g, $g, $n); if (Math::GMPz::Rmpz_cmp_ui($g, 1) > 0) { return undef if (Math::GMPz::Rmpz_cmp($g, $n) == 0); return $g; } } return undef; } say FLT_find_factor("1759590140239532167230871849749630652332178307219845847129"); #=> 12072684186515582507 say FLT_find_factor("28168370236334094367936640078057043313881469151722840306493"); #=> 30426633744568826749 say FLT_find_factor("97967651586822913179896725042136997967830602144506842054615710025444417607092711829309187"); #=> 86762184769343281845479348731 say FLT_find_factor("1129151505892449502375764445221583755878554451745780900429977", 3); #=> 867621847693432818454793487397