forked from moodleou/moodle-quiz_gradingstudents
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexamconfirmationcode.php
More file actions
99 lines (90 loc) · 3.62 KB
/
examconfirmationcode.php
File metadata and controls
99 lines (90 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
<?php
// This file is part of Moodle - http://moodle.org/
//
// Moodle is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// Moodle is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Moodle. If not, see <http://www.gnu.org/licenses/>.
defined('MOODLE_INTERNAL') || die();
/**
* This class implements the OU's 'Confirmation code' algorithm for end-of-course
* assessed tasks. Graders need to enter this into the grading system as a
* checksum to ensure that they are entering marks for the right student / task.
*
* @package quiz_gradingstudents
* @copyright 2013 The Open University
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
*/
class quiz_gradingstudents_report_exam_confirmation_code {
const HASH_START = 5381;
const MODULUS = 882377;
const NUM_CHARS = 21;
const CODE_CHARS = 'BCDFGHJKLMNPQRSTVWXYZ';
const NUM_CODES = 194481; // 21*21*21*21.
/**
* Check for the correct idnumber and generate a confirmation code
* @param string $quizidnumber
* @param string $pi, personal identifier
* @param int $version
* @return NULL or string
*/
public static function get_confirmation_code($quizidnumber, $pi, $version = 1) {
if (!preg_match('~\w+-\w+\.((?i:eca|exm)\d+)~', $quizidnumber, $matches)) {
return null;
}
list($courseshortname, $notused) = explode('.', $quizidnumber, 2);
list($module, $pres) = explode('-', $courseshortname, 2);
$task = core_text::strtoupper($matches[1]);
$module = core_text::strtoupper($module);
$pres = core_text::strtoupper($pres);
return self::calculate_confirmation_code($pi, $module, $pres, $task, $version);
}
/**
* Compute the confirmation code for a student for on a task.
* @param string $pi the student's PI.
* @param string $module the module code, e.g. B747.
* @param string $pres the short presentation code, e.g. 13B.
* @param string $task the task name. E.g. EXM01 or EMA01.
* @param int $version defaults to 1.
* @return string The confirmation code.
*/
public static function calculate_confirmation_code($pi, $module, $pres, $task, $version = 1) {
return self::calculate_hash($pi . $module . $version . $pres . $task);
}
/**
* The raw hash algorithm.
* @param string $string the input string.
* @return string The confirmation code.
*/
public static function calculate_hash($string) {
$cleanstring = str_replace(' ', '', $string);
$hash = self::HASH_START;
$inputlength = strlen($cleanstring);
for ($i = 0; $i < $inputlength; $i += 1) {
$nextchar = ord(substr($cleanstring, $i, 1));
$hash += $nextchar;
if ($nextchar % 2) {
$hash *= 13;
} else {
$hash *= 7;
}
$hash %= self::MODULUS;
}
$hash %= self::NUM_CODES;
$code = '';
for ($i = 0; $i < 4; $i += 1) {
$nextchar = $hash % self::NUM_CHARS;
$code .= substr(self::CODE_CHARS, $nextchar, 1);
$hash = ($hash - $nextchar) / self::NUM_CHARS;
}
return $code;
}
}