static PyObject *dsarand_pynew(PyTypeObject *ty, PyObject *arg, PyObject *kw)
{
struct bin in;
+ unsigned passes = 1;
+ grand *r;
PyObject *rc = 0;
- static const char *const kwlist[] = { "seed", 0 };
+ static const char *const kwlist[] = { "seed", "passes", 0 };
- if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&:new", KWLIST, convbin, &in))
+ if (!PyArg_ParseTupleAndKeywords(arg, kw, "O&|O&:new", KWLIST,
+ convbin, &in, convuint, &passes))
goto end;
- rc = grand_dopywrap(ty, dsarand_create(in.p, in.sz), f_freeme);
+ if (!passes) VALERR("must be positive");
+ r = dsarand_create(in.p, in.sz);
+ if (passes != 1) r->ops->misc(r, DSARAND_PASSES, passes);
+ rc = grand_dopywrap(ty, r, f_freeme);
end:
return (rc);
}
return (rc);
}
+static PyObject *drget_passes(PyObject *me, void *hunoz)
+{
+ grand *r = GRAND_R(me);
+ return (PyInt_FromLong(r->ops->misc(r, DSARAND_PASSES, 0)));
+}
+
+static int drset_passes(PyObject *me, PyObject *val, void *hunoz)
+{
+ grand *r = GRAND_R(me);
+ long n;
+ int rc = -1;
+
+ if (!val) NIERR("__del__");
+ n = PyInt_AsLong(val); if (n == -1 && PyErr_Occurred()) goto end;
+ if (n <= 0) VALERR("must be positive");
+ if (n > ULONG_MAX) VALERR("out of range");
+ r->ops->misc(r, DSARAND_PASSES, (unsigned)n);
+ rc = 0;
+end:
+ return (rc);
+}
+
static const PyGetSetDef dsarand_pygetset[] = {
#define GETSETNAME(op, name) dr##op##_##name
GET (seed, "R.seed -> current generator seed")
+ GETSET(passes, "R.passes -> number of passes to create output")
#undef GETSETNAME
{ 0 }
};
def test_dsarand(me):
seed = T.span(16)
n = C.MP.loadb(seed)
- rng = C.DSARand(seed)
+ rng = C.DSARand(seed, passes = 2)
me.check_rand(rng)
- me.assertEqual(rng.seed, (n + 153 + 3).storeb(16))
+ me.assertEqual(rng.seed, (n + 2*153).storeb(16))
+ me.assertEqual(rng.passes, 2);
+ rng.passes = 1
+ me.check_rand(rng)
+ me.assertEqual(rng.seed, (n + 3*153 + 1).storeb(16))
def test_bbs(me):
ev = T.EventRecorder()