Completed
Push — master ( 505cf6...fbc5dd )
by Ronan
06:58
created

Ssn::validate()   B

Complexity

Conditions 8
Paths 16

Size

Total Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 36
rs 8.0995
c 0
b 0
f 0
cc 8
nc 16
nop 1
1
<?php
2
3
namespace IsoCodes;
4
5
/**
6
 * @example :
7
 * echo Ssn::validate('557-26-9048');
8
 *
9
 * As of 2011 SSN's are completely randomized
10
 * @link    : http://www.socialsecurity.gov/employer/randomization.html)
11
 * @source  : http://haxorfreek.15.forumer.com/a/us-social-security-number-ssn-generator_post1847.html
12
 * @source  : https://gist.github.com/Kryptonit3/7b6bff5abab4a62e2b796a0e5a9ab94e
13
 *
14
 * Some special numbers are never allocated:
15
 * Numbers with all zeros in any digit group (000-##-####, ###-00-####, ###-##-0000).[36][37]
16
 * Numbers with 666 or 900–999 (Individual Taxpayer Identification Number) in the first digit group.[36]
17
 * special cases to care bout:
18
 * @link     : https://stackoverflow.com/questions/1517026/how-can-i-validate-us-social-security-number/18385786#18385786
19
 */
20
class Ssn implements IsoCodeInterface
21
{
22
23
    /**
24
     * SSN validation.
25
     *
26
     * @param string $ssn
27
     *
28
     * @return bool
29
     */
30
    public static function validate($ssn)
31
    {
32
        $ssn = trim($ssn);
33
34
        // Must be in format AAA-GG-SSSS or AAAGGSSSS
35
        if (!preg_match("/^([0-9]{9}|[0-9]{3}-[0-9]{2}-[0-9]{4})$/", $ssn)) {
36
            return false;
37
        }
38
39
        $forbidden = [
40
            '078-051-120', // Woolworth Wallet Fiasco
41
            '219-099-999'  // Was used in an ad by the Social Security Administration
42
        ];
43
44
        if (in_array($ssn, $forbidden)) {
45
            return false;
46
        }
47
48
        $ssnFormatted = (strlen($ssn) == 9) ? preg_replace("/^([0-9]{3})([0-9]{2})([0-9]{4})$/", "$1-$2-$3", $ssn) : $ssn;
49
        $ssn_array = explode('-', $ssnFormatted);
50
51
        // number groups must follow these rules:
52
        // * no single group can have all 0's
53
        // * first group cannot be 666, 900-999
54
        // * second group must be 01-99
55
        // * third group must be 0001-9999
56
57
        foreach ($ssn_array as $group) {
58
            if ($group == 0) {
59
                return false;
60
            }
61
        }
62
63
        // Forbidden numbers
64
        return !($ssn_array[0] == 666 || $ssn_array[0] === '000' || $ssn_array[0] > 899);
65
    }
66
}
67