Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Social Security Number Validation That Accepts Dashes, Spaces or No Spaces

Tags:

regex

Social Security numbers that I want to accept are:

xxx-xx-xxxx (ex. 123-45-6789)
xxxxxxxxx (ex. 123456789)
xxx xx xxxx (ex. 123 45 6789)

I am not a regex expert, but I wrote this (it's kind of ugly)

^(\d{3}-\d{2}-\d{4})|(\d{3}\d{2}\d{4})|(\d{3}\s{1}\d{2}\s{1}\d{4})$

However this social security number passes, when it should actually fail since there is only one space

12345 6789

So I need an updated regex that rejects things like

12345 6789
123 456789

To make things more complex it seems that SSNs cannot start with 000 or 666 and can go up to 899, the second and third set of numbers also cannot be all 0.

I came up with this

^(?!000|666)[0-8][0-9]{2}[ \-](?!00)[0-9]{2}[ \-](?!0000)[0-9]{4}$

Which validates with spaces or dashes, but it fails if the number is like so

123456789

Ideally these set of SSNs should pass

123456789
123 45 6789
123-45-6789
899-45-6789
001-23-4567

And these should fail

12345 6789
123 456789
123x45x6789
ABCDEEEEE
1234567890123
000-45-6789
123-00-6789
123-45-0000
666-45-6789
like image 332
wiredniko Avatar asked Dec 05 '22 01:12

wiredniko


2 Answers

More complete validation rules are available on CodeProject at http://www.codeproject.com/Articles/651609/Validating-Social-Security-Numbers-through-Regular. Copying the information here in case the link goes away, but also expanding on the codeproject answer a bit.

A Social Security number CANNOT :

  • Contain all zeroes in any specific group (ie 000-##-####, ###-00-####, or ###-##-0000)
  • Begin with ’666′.
  • Begin with any value from ’900-999′
  • Be ’078-05-1120′ (due to the Woolworth’s Wallet Fiasco)
  • Be ’219-09-9999′ (appeared in an advertisement for the Social Security Administration)

This RegEx taken from the referenced CodeProject article will validate all Social Security numbers according to all the rules - requires dashes as separators.

^(?!219-09-9999|078-05-1120)(?!666|000|9\d{2})\d{3}-(?!00)\d{2}-(?!0{4})\d{4}$

Same with spaces, instead of dashes

^(?!219 09 9999|078 05 1120)(?!666|000|9\d{2})\d{3} (?!00)\d{2} (?!0{4})\d{4}$

Finally, this will validate numbers without spaces or dashes

^(?!219099999|078051120)(?!666|000|9\d{2})\d{3}(?!00)\d{2}(?!0{4})\d{4}$

Combining the three cases above, we get the

Answer

^((?!219-09-9999|078-05-1120)(?!666|000|9\d{2})\d{3}-(?!00)\d{2}-(?!0{4})\d{4})|((?!219 09 9999|078 05 1120)(?!666|000|9\d{2})\d{3} (?!00)\d{2} (?!0{4})\d{4})|((?!219099999|078051120)(?!666|000|9\d{2})\d{3}(?!00)\d{2}(?!0{4})\d{4})$
like image 84
George Avatar answered Feb 01 '23 23:02

George


To solve your problem with dashes, spaces, etc. being consistent, you can use a backreference. Make the first separator a group and allow it to be optional - ([ \-]?). You can then reference it with \1 to make sure the second separator is the same as the first one:

^(?!000|666)[0-9]{3}([ -]?)(?!00)[0-9]{2}\1(?!0000)[0-9]{4}$

See it here (thanks @Tushar)

like image 31
Szymon Avatar answered Feb 02 '23 00:02

Szymon