Bug#537952: Use more random random seed than localtime

Jonathan Yu frequency at cpan.org
Fri Jul 31 01:53:00 UTC 2009


On Thu, Jul 30, 2009 at 8:09 PM, Don Armstrong<don at donarmstrong.com> wrote:
> On Thu, 30 Jul 2009, Jonathan Yu wrote:
>> On Thu, Jul 30, 2009 at 7:35 PM, Don Armstrong<don at donarmstrong.com> wrote:
>> > On Thu, 30 Jul 2009, Jonathan Yu wrote:
>> >> I should also note that changing the patch to this:
>> >> +void
>> >> +set_default_seed(long time)
>> >> +       PREINIT:
>> >> +       long seed;
>> >> +       CODE:
>> >> +       seed = Perl_get_seed;
>> >> +       setall(seed, seed);
>> >>
>> >> Yielded the same error. Am I missing something about how to use setall()?
>> >
>> > Yes. You're missing the modulus which is present in my second patch.
>>
>> I don't think I am. Here is the code prior to that bit:
>
> Ugh. Puting the limitation of setall into this function is silly. But
> regardless, you need *two* diferent seed values. Read my patch again.
Aha, that is indeed what was causing the test failures. But for some
reason not even using "time" and "seed" as the two parameters would
work, presumably because time didn't fall into the mod restriction
that setall has.
>
>> I did that so that if Perl_seed isn't available, it would fall back to
>> using 'time' (which is passed in as a parameter).
>
> Which is wrong and not aplicable to debian regardless. Let the
> upstream maintainer decide this if the want to support ancient perls.
I would prefer not to break things for older versions of Perl (even if
they're ancient and awful) where possible. In this case it wasn't
overly *difficult* to accomodate, but it sure is ugly. I'm hoping
upstream will come up with something better, though I'll propose it as
a fix.

I added a feature (per your advice) to warn if Perl_seed isn't
available. Hopefully this means our users will realize that the
default seeding mechanism is crappy, and choose something better in
its place.

If this is acceptable to you I'll try to get it uploaded.

--- a/Random.pm
+++ b/Random.pm
@@ -73,7 +73,13 @@


 ### set seeds by default
-salfph(scalar(localtime()));
+if ($] > 5.008001) {
+  set_default_seed();
+}
+else {
+  cluck "Your Perl is older than 5.8.1, the default seed is 'localtime'";
+  salfph(scalar localtime);
+}

 #####################################################################
 #                    RANDOM DEVIATE GENERATORS                     #
--- a/Random.xs
+++ b/Random.xs
@@ -11,6 +11,23 @@
 #include "randlib.h"
 #include "helper.h"

+#define PERL_VERSION_ATLEAST(a,b,c)                            \
+  (PERL_REVISION > (a)                                         \
+   || (PERL_REVISION == (a)                                    \
+       && (PERL_VERSION > (b)                                  \
+           || (PERL_VERSION == (b) && PERL_SUBVERSION >= (c)))))
+
+#if PERL_VERSION_ATLEAST (5,8,1)
+/* For whatever reason, the random seeds need to be in 1..2^30; the below will
+ * be uniformly distributed assuming the seed value is uniformly distributed.
+ */
+#define default_seed_mechanism \
+  setall((long)(Perl_seed(aTHX) % 1073741824L), \
+         (long)(Perl_seed(aTHX) % 1073741824L));
+#else /* Perl < 5.8.1 */
+#define default_seed_mechanism not_here("Perl_seed");
+#endif
+
 static int
 not_here(s)
 char *s;
@@ -38,6 +55,10 @@

 MODULE = Math::Random          PACKAGE = Math::Random

+void
+set_default_seed()
+        CODE:
+        default_seed_mechanism;

 double
 genbet (aa,bb)





More information about the pkg-perl-maintainers mailing list