From 50a946f5bb22b0776ce2df2f8dc699be2339153d Mon Sep 17 00:00:00 2001 From: Tim Hunt Date: Tue, 29 Oct 2013 16:19:24 +0000 Subject: [PATCH] MDL-42598 quiz variant randomisation not random enough. A student would get the same question variants (for example for a calculated question) on their first attempt at both copies of a duplicated quiz. --- mod/quiz/startattempt.php | 4 +++- question/engine/lib.php | 11 +++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/mod/quiz/startattempt.php b/mod/quiz/startattempt.php index 4a47194b19a..7bbfca549a1 100644 --- a/mod/quiz/startattempt.php +++ b/mod/quiz/startattempt.php @@ -209,7 +209,9 @@ if (!($quizobj->get_quiz()->attemptonlast && $lastattempt)) { $variantoffset = $attemptnumber; } $quba->start_all_questions( - new question_variant_pseudorandom_no_repeats_strategy($variantoffset), $timenow); + new question_variant_pseudorandom_no_repeats_strategy( + $variantoffset, $attempt->userid, $quizobj->get_quizid()), + $timenow); // Update attempt layout. $newlayout = array(); diff --git a/question/engine/lib.php b/question/engine/lib.php index ced2c29e571..4c0f90ff592 100644 --- a/question/engine/lib.php +++ b/question/engine/lib.php @@ -884,12 +884,15 @@ class question_variant_pseudorandom_no_repeats_strategy /** @var int the user id the attempt belongs to. */ protected $userid; + /** @var string extra input fed into the pseudo-random code. */ + protected $extrarandomness = ''; + /** * Constructor. * @param int $attemptno The attempt number. * @param int $userid the user the attempt is for (defaults to $USER->id). */ - public function __construct($attemptno, $userid = null) { + public function __construct($attemptno, $userid = null, $extrarandomness = '') { $this->attemptno = $attemptno; if (is_null($userid)) { global $USER; @@ -897,6 +900,10 @@ class question_variant_pseudorandom_no_repeats_strategy } else { $this->userid = $userid; } + + if ($extrarandomness) { + $this->extrarandomness = '|' . $extrarandomness; + } } public function choose_variant($maxvariants, $seed) { @@ -904,7 +911,7 @@ class question_variant_pseudorandom_no_repeats_strategy return 1; } - $hash = sha1($seed . '|user' . $this->userid); + $hash = sha1($seed . '|user' . $this->userid . $this->extrarandomness); $randint = hexdec(substr($hash, 17, 7)); return ($randint + $this->attemptno) % $maxvariants + 1;