Luhn::calculateCheckDigit()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
1
<?php
2
3
/*
4
 * This file is part of questocat/bank-card package.
5
 *
6
 * (c) questocat <[email protected]>
7
 *
8
 * This source file is subject to the MIT license that is bundled
9
 * with this source code in the file LICENSE.
10
 */
11
12
namespace Questocat\BankCard;
13
14
/**
15
 * Luhn 算法.
16
 *
17
 * @see https://zh.wikipedia.org/wiki/Luhn%E7%AE%97%E6%B3%95
18
 */
19
class Luhn
20
{
21
    /**
22
     * Verify the check digit.
23
     *
24
     * @param string cardNumber
25
     *
26
     * @return bool
27
     */
28
    public function verify($cardNumber)
29
    {
30
        $originalCardNumber = $this->prepare($cardNumber);
31
32
        $cardNumber = $this->excludeCheckDigit($originalCardNumber);
33
34
        $luhmSum = $this->calculateLuhmSum($cardNumber);
35
36
        $checkCode = $this->checkDigit($originalCardNumber);
37
38
        if (0 === ($luhmSum + $checkCode) % 10) {
39
            return true;
40
        }
41
42
        return false;
43
    }
44
45
    /**
46
     * Calculate the check digit.
47
     *
48
     * @param string $number
49
     *
50
     * @return string
51
     */
52
    public function calculateCheckDigit($number)
53
    {
54
        $luhmSum = $this->calculateLuhmSum($number);
55
56
        return 10 - ($luhmSum % 10);
57
    }
58
59
    /**
60
     * Prepare the bank card number.
61
     *
62
     * @param string $cardNumber
63
     *
64
     * @return string
65
     */
66
    protected function prepare($cardNumber)
67
    {
68
        $cardNumber = str_replace(' ', '', trim($cardNumber));
69
70
        return $cardNumber;
71
    }
72
73
    /**
74
     * Returns the check digit of card number.
75
     *
76
     * @param string $cardNumber
77
     *
78
     * @return int
79
     */
80
    protected function checkDigit($cardNumber)
81
    {
82
        return substr($cardNumber, -1);
83
    }
84
85
    /**
86
     * Returns the no check digit of card number.
87
     *
88
     * @param string $cardNumber
89
     *
90
     * @return string
91
     */
92
    protected function excludeCheckDigit($cardNumber)
93
    {
94
        return substr($cardNumber, 0, -1);
95
    }
96
97
    /**
98
     * Calculate the Luhm checksum.
99
     *
100
     * @param string $number
101
     *
102
     * @return int
103
     */
104
    protected function calculateLuhmSum($number)
105
    {
106
        $len = strlen($number);
107
        $luhmSum = 0;
108
        $j = 1;
109
110
        for ($i = $len - 1; $i >= 0; --$i) {
111
            $k = intval($number[$i]);
112
            if (1 == $j % 2) {
113
                $k *= 2;
114
                $k = intval($k / 10) + $k % 10;
115
            }
116
117
            $luhmSum += $k;
118
            ++$j;
119
        }
120
121
        return $luhmSum;
122
    }
123
}
124