xref: /web-php/manual/spam_challenge.php (revision 59c070f5)
1<?php
2
3// simple and stupid SPAM protection (using little challenges)
4
5const NUMS = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine'];
6
7function plus($a, $b) {
8    return $a + $b;
9}
10
11function gen_plus($a) {
12    return mt_rand(0, 9 - $a);
13}
14
15function minus($a, $b) {
16    return $a - $b;
17}
18
19function gen_minus($a) {
20    return mt_rand(0, $a);
21}
22
23function print_infix($name, $a, $b) {
24    return "$a $name $b";
25}
26
27function print_prefix($name, $a, $b) {
28    return "$name($a, $b)";
29}
30
31const CHALLENGES = [
32    // name, print, generator
33    ['max',   'print_prefix'],
34    ['min',   'print_prefix'],
35    ['minus', 'print_infix', 'gen_minus'],
36    ['plus',  'print_infix', 'gen_plus'],
37];
38
39// generate a challenge
40function gen_challenge() {
41    $c = CHALLENGES[mt_rand(0, count(CHALLENGES) - 1)];
42
43    $a = mt_rand(0, 9);
44    $an = NUMS[$a];
45    $b = isset($c[2]) ? $c[2]($a) : mt_rand(0, 9);
46    $bn = NUMS[$b];
47
48    return [$c[0], $an, $bn, $c[1]($c[0], $an, $bn)];
49}
50
51// test an answer for validity
52function test_answer($name, $an, $bn, $answer) {
53    foreach (CHALLENGES as $x) {
54        if ($x[0] === $name) {
55            $c = $x;
56            break;
57        }
58    }
59
60    $a = array_search($an, NUMS, false);
61    $b = array_search($bn, NUMS, false);
62
63    if (empty($c) || $a === false || $b === false) return false;
64
65    return (NUMS[$c[0]($a, $b)] === $answer);
66}
67