Test Setup Failed
Pull Request — master (#1)
by Claudson
09:10 queued 02:23
created

helpers.php ➔ module10()   A

Complexity

Conditions 4
Paths 5

Size

Total Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
nc 5
nop 1
dl 0
loc 19
rs 9.6333
c 0
b 0
f 0
1
<?php
2
3
if (! function_exists('starts_with')) {
4
    /**
5
     * Checks if a string starts with a given substring.
6
     */
7
    function starts_with(string $needle, string $haystack): bool
8
    {
9
        return substr($haystack, 0, strlen($needle)) === $needle;
10
    }
11
}
12
13
if (! function_exists('module10')) {
14
    /**
15
     * Calculates the module 10 for the given input.
16
     */
17
    function module10(string $input): string
18
    {
19
        $reversedInput = strrev($input);
20
        $sum = 0;
21
22
        for ($inputSize = strlen($reversedInput), $i = 0; $i < $inputSize; $i++) {
23
            $value = (int) (substr($reversedInput, $i, 1));
24
            $productResult = $value * (0 == $i % 2 ? 2 : 1);
25
26
            if ($productResult > 9) {
27
                // Sum the number digits before add to the total sum.
28
                $sum += array_sum(str_split($productResult));
29
            } else {
30
                $sum += $productResult;
31
            }
32
        }
33
34
        return (ceil($sum / 10) * 10) - $sum;
35
    }
36
}
37
38
if (! function_exists('module11')) {
39
    /**
40
     * Calculates the module 11 for the given input.
41
     *
42
     * @example CPF: module11('input', 2, 12, true)
43
     * @example CNPJ: module11('input', 2, 9, true)
44
     * @example PIS,C/C,Age: module11('input', 1, 9, true)
45
     * @example RG SSP-SP: module11('input', 1, 9, false)
46
     *
47
     * @param string $input                   Input numbers without the verification digit
48
     * @param int    $amountOfDigits          Amount of verification digits to calculate
49
     * @param int    $multiplicationThreshold The max weight to multiply the numbers
50
     * @param bool   $timesTen                Whether or not multiply the sum by ten. True returns the digit, false the rest of the division
51
     */
52
    function module11(string $input, int $amountOfDigits = 1, int $multiplicationThreshold = 9, bool $timesTen = true): string
53
    {
54
        if (! $timesTen) {
55
            $amountOfDigits = 1;
56
        }
57
58
        for ($n = 1; $n <= $amountOfDigits; $n++) {
59
            $sum = 0;
60
            $weight = 2;
61
            for ($i = strlen($input) - 1; $i >= 0; $i--) {
62
                $sum += $weight * (int) (substr($input, $i, 1));
63
                if (++$weight > $multiplicationThreshold) {
64
                    $weight = 2;
65
                }
66
            }
67
68
            if ($timesTen) {
69
                $digit = fmod(fmod(($sum * 10), 11), 10);
70
            } else {
71
                $digit = fmod($sum, 11);
72
            }
73
            $input .= (string) $digit;
74
        }
75
76
        return substr($input, strlen($input) - $amountOfDigits);
77
    }
78
}
79