The last time I tried that, someone removed *all* the implementation links claiming "Wikipedia is not a code repository". I get the point, but sometimes having a link to some actual working code is useful. It's a very inconsistent standard.

Oh, and thank you very much for doing this. I have an edit queued up for after work.

]]>This came to mind when wondering why Math::TrulyRandom wasn't on the list. It's mentioned in the core documentation for rand. It's also broken in many ways and has no owner. However it has no dependent distributions so ends up with a score of 6 (my estimate). In this particular case I think the correct answer is to patch the core documentation to remove any mention of the module.

Said module brings up another point, which is that arguably the module should go away entirely.

]]>Having the ability for a tester to retract results would be nice. I once tried smoking on a Windows box, which went fine until it hit the too-many-characters-on-a-command-line issue and then started spewing fail reports that had nothing to do with the modules being tested. Not only might one want to retract individual reports, but it would be nice to have a "Remove all reports for configuration ID XYZ: that platform/configuration was borked."

Having the ability to attach comments to smoke results (both by the tester and module owner) seems useful, but I'm not sure how many people would really dig that deep.

Re: rating of testers, I'd like to see if separated out into (1) tester, and (2) configuration. #1 is purely how responsive the person is. #2 is a rating of the results that are coming from from that smoker process.

Reason one for splitting: some people do smoking on multiple devices, so indicating how good the results are per configuration is useful. They may be running a 5.16-on-x86-gcc-Linux setup as well as a 5.19.2-on-ARM-clangdev-BSD, where the former is doing well but the latter may have some failures that turn out to be related to the dev Perl or dev compiler or whatever. This does require some way to identify a smoking configuration in addition to the tester id, and get a new configuration id once the tester has decided something has changed enough to justify it.

Reason two for splitting: Let's say I did something dumb and one of my smokers sent out bad reports. Immediately 10 people give me -1 votes. Well I may as well quit smoking forever, because I'll never get +1 votes back without pestering people to upvote me (at which point those old bad results now start showing up and I get -1'd again).

]]>Another example of this is the change to SvUPGRADE(sv), which used to return a value and changed to a void function in 5.17.8ish (it was indicated as being a void function in 2005). This broke a few Crypto modules, albeit the fix is really easy. But for a user who just wanted some upstream module, this means upgrading Perl made things stop working.

The module dependency issue is one reason I found to, when given the choice of two equal-for-my-use modules, one having 2 total chain non-core dependencies and the other having over 40, prefer the smaller.

]]>Broken dependency. Mirod already said it, but it's so common.

Incompatible operating system I might generalize to incompatible platform. That includes weirdness like different tmpfile behavior, NFS tmpdir, classic O/S issues, Win32 issues, big- vs. little-endian, compiler differences (e.g. the MSVC compiler).

Something that is similar to the above two but slightly different is wacky broken dependencies already installed. When I look at ActiveState build logs, some of their old systems have the right version of one of my dependencies, but for some reason it acts differently on their system than any other. Put another way, if my system has a broken/non-standard Math::BigInt installed, then I may get what seem like mysterious test failures when trying to install a module or its dependencies.

This may qualify as one of the others including broken module, but I've seen a number of cases where in my environment, 999/1000 test cases pass but one doesn't. This is often something like "testing interoperability with Obscure::Module" and Obscure::Module has changed something that invalidates the test. (Danger ahead) When I want the module for a one-off non-production experiment that has nothing to do with Obscure::Module I sometimes just force the install and typically everything works fine.

P.S. CPAN Testers, yay.

]]>Module prime factors divisorsPari includes 1 and n , MFXS and MPU do not (it's easy enough to add or remove them). As an example, 2^90-1 has 13 prime factors (11 unique), and 4094 divisors (plus 1 and n).]]>

------------------ ------------- -----------

Math::Big::Factors factors_wheel -

Math::Factor::XS prime_factors factors

Math::Factoring factor -

Math::Prime::Util factor all_factors

Math::Pari factorint divisors

If you want to factor 30+ digit numbers I recommend additionally installing Math::BigInt::GMP and Math::Prime::Util::GMP.

factor.pl 2**63-1

factor.pl 'nth_prime(100000)*pn_primorial(10)*random_nbit_prime(90)'

This is just a brief look so I chose some easy numbers:

2**38-1 (3,174763,524287)

2**90-1 (3,3,3,7,11,19,31,73,151,331,631,23311,18837001)

2**150-1 (3,3,7,11,31,151,251,331,601,1801,4051,100801,

10567201,1133836730401)

and some "hard" numbers:

2**62-1 (3,715827883,2147483647)

2**95-1 (31,191,524287,420778751,30327152671)

2**195-1 (7,31,79,151,8191,121369,145295143558111,

134304196845099262572814573351)2**250-1 (3,11,31,251,601,1801,4051,229668251,269089806001,

4710883168879506001,5519485418336288303251)

An aside: *everyone's thoughts on what "small", "big", "easy", "hard" mean differ. To some, a 19-digit number is big, while to many people working on modern factoring that size is completely trivial, and anything under 100-digits is a yawn. My goal is to make it easy to factor 50-80 digit numbers in a reasonable time from Perl. If you are seriously looking for larger or better methods, I recommend yafu, msieve, GMP-ECM, and GGNFS.*

So first let's look at the modules:

- Math::Big::Factors. I believe this was intended as an example of using Math::BigInt, but there are some modules actually using it. The main problem is that is super slow (slower than a simple trial division loop in many cases).
- Math:Factor::XS. Nicely coded trial division in C. Great for easy native size integers, slower than need be for ones with two large factors, and doesn't support bigints.
- Math::Factoring. Leto's placeholder for factoring algorithms in Perl+Math::GMPz. Unfortunately it currently only does trial division, so it only works well on easy numbers. Also be careful to give it only native or Math::GMPz inputs or it blows up.
- Math::Pari. Perl interface to the Pari library (2.1 by default, 2.3 possible if hand-built, 2.5+ not supported). Downside: licensing and portability issues on some platforms. Upside:
**lots**of functions, integer factoring is fast and has a relatively predictable slowdown as the input gets larger. Uses SQUFOF, Pollard Rho, ECM, and MPQS. - Math::Prime::Util. The module I've been working on lately. Small numbers are factored in C using Pollard Rho, SQUFOF, Pollard p-1, and HOLF. For BigInts we see if Math::Prime::Util::GMP is installed and use that if so, otherwise various Perl methods are used: Trial, HOLF, Pollard's Rho, Pollard's p-1, and 2-stage ECM.
- Math::Prime::Util::GMP. This module contains C+GMP code for various tasks and is meant to be a backend for Math::Prime::Util -- install it if you have GMP and most big integer functions speed up. For factoring this is
**much**faster than Perl+Math::BigInt::GMP. It uses a combination of Trial, native SQUFOF, 2-stage Pollard p-1, 2-stage ECM, Pollard Rho, and a simple Quadratic Sieve.

I took a fresh 5.16.2 perlbrew on an x86 Ubuntu machine and installed Math::BigInt::GMP to start, then tried various modules on some simple examples. I installed fresh versions of each module with CPAN before running. Timing results, in seconds, from the command line:

38 90 150 62 95 195 250 ------------ ------ ------ ------ ------ ------ ------ ------ Math::Big 13.7 369 >600 >600 >600 MF::XS 0.02 1.78 M::Factoring 0.22 0.12 7.86 493 302 >600 MPU 0.05 0.16 1.39 0.05 2.03 120+ 600+ MPU::GMP 0.05 0.05 0.06 0.05 0.06 0.40 1.57 Math::Pari 0.05 0.06 0.06 0.06 0.06 0.35 5.65

This is just a gross look, factoring a single number, so anything under 0.1 seconds is reflecting the overhead of starting Perl more than the actual time taken. Both Math::Pari and Math::Prime::Util do some startup work such as creating a small set of primes used for other functions, which the other modules don't do.

Math::Big::Factor: I tried different sizes for the factor wheel and 5 was the fastest for these examples. It took over 6 minutes to factor 2^90-1, which a trial division loop can do in under a second. I stopped it after 15 minutes on 2^150-1, which a trial division loop can do in a bit over 5 minutes.

Math::Factor::XS is super fast for the small example, but certainly slower than need be for 2^62-1. Its maximum size is MAX(sizeof(unsigned long), sizeof(UV)), so either 32-bit or 64-bit.

Math::Factoring will be pretty interesting once algorithms get added, and I'm thinking of submitting a patch to support some of the simpler methods from MPU like Pollard Rho (with Brent's improvements), 2-stage p-1, Fermat, HOLF, and possibly ECM. Using Math::GMPz directly should make it faster than using Math::BigInt objects.

Math::Prime::Util using pure Perl does a pretty good job on most of the numbers. The two largest examples are found using ECM, which is why the '+' sign on the time -- exactly how fast they get found depends on the random curves selected.

Math::Pari and Math::Prime::Util::GMP are the clear time winners, finding all the factors of the small examples basically instantly. Both of them factor random 30-digit numbers in under 10ms, and average under a second for random 60 digit numbers.

Edit for reference: command lines used:

]]>

perl -Mbigint=lib,GMP -MMath::Big::Factors=factors_wheel -E 'my $n = 2**38-1; say join ",", factors_wheel($n, 5);'

perl -MMath::Factor::XS=prime_factors -E 'my $n = 2**38-1; say join ",", prime_factors($n);'

perl -MMath::Factoring=factor -Mbigint=lib,GMP -E 'my $n = 2**38-1; say join ",", factor(Math::GMPz->new("$n"));'

perl -MMath::Prime::Util=factor -Mbigint=lib,GMP -E 'my $n = 2**38-1; say join ",", factor($n);

perl -MMath::Pari=factorint -Mbigint=lib,GMP -E 'my $n = 2**38-1; my ($pn,$pc) = @{factorint($n)}; say join ",", map { ($pn->[$_]) x $pc->[$_] } 0 .. $#$pn'

Many of the modules I use and feel like I have a review of are related to modules I've written. This makes me nervous about writing reviews, as there was a *reason* I wrote my own module. Writing a review like "this module is fine for toy examples, but for real data use MyModule" is crass. I'd be interested in hearing what others think. Clearly one would like to note to others that there may be a superior module, on the other hand I've also had mostly good experiences just talking directly to other module owners to get improvements made for the biggest issues I have.

I've been thinking I would like to do some reviews of a few module areas like Neil B. and others have done, but again when I own one of the modules, someone is going to take issue with any comments I make. I'm also seeing it from the point of view of one of the module creators so will have the same priorities and blind spots.

]]>I decided to go ahead and do the Pari removal, and it's on CPAN as Alt::Crypt::RSA::BigInt. This uses Ingy's Alt framework -- install the Alt version and you get a new shiny Crypt::RSA. Install the old version and you're back again. There are no Pari dependencies, and if Math::BigInt::GMP is used, it's **5 to 11 times faster**. I decided to use Math::BigInt directly, as that makes it very portable, though the speed without either the GMP or Pari backend leaves much to be desired.

This also fixes, to the best of my knowledge, all 11 of the open RT issues with Crypt::RSA, and adds some new features (e.g. SHA256, SHA224, SHA384, SHA512 support, fix Key::Private::SSH, and add new ciphers). It also fixes some serious issues with the key generation caused by Crypt::Primes. I intentionally left the API and internal structure as identical as possible. There's an argument to be made for a new RSA module, but that wasn't the point for this change.

The conversion of the math inside Crypt::RSA was relatively straightforward. The big issues were the dependencies. Math::Prime::Util has fast random prime generation and primality testing, which solves that portion. Fortuitously, David Oswald released Bytes::Random::Secure right before I started on the conversion, and it met all my needs for replacing Crypt::Random.

]]>I used Zotero when I did my last degree and recommend it highly. Especially for storing not only citations, but PDFs of the papers. Really nice for multiple computers: put it together at home, pull it up for advisor at school, then again in lab for coding. Export to BibTeX as needed.

]]>