Completed
Push — master ( 329b2d...d6853a )
by Mohamed
15s queued 13s
created

UniqueUid::ValidateCheckCharacter()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 27

Duplication

Lines 11
Ratio 40.74 %

Importance

Changes 0
Metric Value
dl 11
loc 27
rs 9.488
c 0
b 0
f 0
cc 3
nc 3
nop 1
1
<?php
2
3
namespace Lsf\UniqueUid;
4
5
class UniqueUid
6
{
7
    static $charSet;
8
    static $maxCharLen;
9
10
    public function __construct()
11
    {
12
        self::$charSet = '2346789BCDFGHJKMPQRTVWXY';
13
        self::$maxCharLen = strlen(self::$charSet);
14
    }
15
16
    /**
17
     * set custom charset for the Unique ID
18
     *
19
     * @param string $characters
20
     * @return void
21
     */
22
    public function setCharSet($characters)
23
    {
24
        self::$charSet = $characters;
25
        $this->setCharLen($characters);
26
    }
27
28
    /**
29
     * Set charset Len
30
     *
31
     * @param string $characters
32
     * @return void
33
     */
34
    public function setCharLen($characters)
35
    {
36
        self::$maxCharLen = strlen($characters);
37
    }
38
39
    /**
40
     * TO the the Code Point form the Character set
41
     *
42
     * @param string $character
43
     * @return integer
44
     */
45
    public static function CodePointFromCharacter($character)
46
    {
47
        $characters = array_flip(str_split(self::$charSet));
48
        return $characters[$character];
49
    }
50
51
    /**
52
     * Get the Character set form the Code Point
53
     *
54
     * @param integer $codePoint
55
     * @return string
56
     */
57
    public static function CharacterFromCodePoint($codePoint)
58
    {
59
        $characters = str_split(self::$charSet);
60
        return $characters[$codePoint];
61
    }
62
63
    /**
64
     * Get the number of Valid characters for Check digit
65
     *
66
     * @return void
67
     */
68
    public static function NumberOfValidCharacters()
69
    {
70
        return strlen(self::$charSet);
71
    }
72
73
    /**
74
     * This function will pass values to random generator.
75
     * Our function has 1 digit to 25 options
76
     * @length number - length of expected 
77
     * @split number - split range
78
     * @return string
79
     **/
80
    public static function getUniqueAlphanumeric($length = 9, $split = 3)
81
    {
82
        $token = "";
83
84
        // adjust the check digit place
85
        $length = $length - 1;
86
87
        for ($i = 0; $i < $length; $i++) {
88
            $token .= self::$charSet[random_int(0, self::$maxCharLen - 1)];
89
        }
90
91
        $checkChar = self::GenerateCheckCharacter($token);
92
        $token .= $checkChar;
93
        $token  = self::format($token, $split);
94
        return $token;
95
    }
96
97
    /**
98
     * Format the ID with given split range
99
     *
100
     * @param string $token
101
     * @return string
102
     */
103
    public  static function format($token, $split)
104
    {
105
        $partitions = str_split($token, $split);
106
        $length = count($partitions);
107
        $newToken = '';
108
        for ($i = 0; $i < $length; $i++) {
109
            $newToken .= '-' . $partitions[$i];
110
        }
111
        return substr($newToken, 1, strlen($newToken));
112
    }
113
114
    /**
115
     * Check the valid ID
116
     *
117
     * @param string $token
118
     * @return boolean
119
     */
120
    public static function isValidUniqueId($token)
121
    {
122
        // get the length of the token
123
124
        //remove - form the token
125
        $token = str_replace("-", "", $token);
126
127
        $length = strlen($token);
128
129
        // validate the character set
130
        $valid = preg_match("/^[" . self::$charSet . "]/", $token);
131
        if (!$valid) {
132
            return false;
133
        } else {
134
            //get the check character from the token
135
            $checkChar = str_split($token)[$length - 1];
136
137
            // remove the check digit from the token
138
            $token = substr($token, 0, -1);
139
140
            // get the valid check character
141
            $ValidCheckChar = self::GenerateCheckCharacter($token);
142
            return $checkChar == $ValidCheckChar;
143
        }
144
    }
145
146
    /**
147
     * Luhn mod N algorithm
148
     * @input string
149
     * @return string
150
     **/
151
    public static function GenerateCheckCharacter($checkNumber)
152
    {
153
        $length = strlen($checkNumber) - 1;
154
        $factor = 2;
155
        $total_sum = 0;
156
        $n = self::NumberOfValidCharacters();
157
158
        // Starting from the right and working leftwards is easier since
159
        // the initial "factor" will always be "2".
160
        for ($i = ($length); $i >= 0; --$i) {
161
            $codePoint = self::codePointFromCharacter($checkNumber[$i]);
162
            $added = $factor * $codePoint;
163
164
            // Alternate the "factor" that each "codePoint" is multiplied by
165
            $factor = ($factor == 2) ? 1 : 2;
166
167
            // Sum the digits of the "addend" as expressed in base "n"
168
            $added = ($added / $n) + ($added % $n);
169
            $total_sum += $added;
170
        }
171
172
        // Calculate the number that must be added to the "sum"
173
        // to make it divisible by "n".
174
        $reminder = $total_sum % $n;
175
        $checkCodePoint  = ($n - $reminder) % $n;
176
        return  self::CharacterFromCodePoint($checkCodePoint);
177
    }
178
}
179