Quelqu'un sait-il comment améliorer cette fonction? Je ne crains pas de raccourcir le code, je suis sûr que cela pourrait être fait avec une meilleure expression rationnelle, je suis plus préoccupé par la logique correcte. J'ai eu beaucoup de mal à trouver de la documentation pour les numéros SSN. La plupart des règles que j'utilise ci-dessous proviennent d'autres programmeurs qui travaillent dans le secteur du crédit (aucune source citée).
Merci pour toute idée!
public static bool isSSN(string ssn)
{
Regex rxBadSSN = new Regex(@"(\d)\1\1\1\1\1\1\1\1");
//Must be 9 bytes
if(ssn.Trim().Length != 9)
return false;
//Must be numeric
if(!isNumeric(ssn))
return false;
//Must be less than 772999999
if( (Int32)Double.Parse(ssn.Substring(0,3)) > 772 )
{
//Check for Green Card Temp SSN holders
// Could be 900700000
// 900800000
if(ssn.Substring(0,1) != "9")
return false;
if(ssn.Substring(3,1) != "7" && ssn.Substring(3,1) != "8")
return false;
}
//Obviously Fake!
if(ssn == "123456789")
return false;
//Try again!
if(ssn == "123121234")
return false;
//No single group can have all zeros
if(ssn.Substring(0,3) == "000")
return false;
if(ssn.Substring(3,2) == "00")
return false;
if(ssn.Substring(5,4) == "0000")
return false;
//Check to make sure the SSN number is not repeating
if (rxBadSSN.IsMatch(ssn))
return false;
return true;
}
METTRE À JOUR
Le 25 juin 2011, la SSA a modifié le processus d'attribution du SSN en «randomisation du SSN». [27] La randomisation du SSN affecte le processus d'attribution du SSN des manières suivantes:
Il élimine la signification géographique des trois premiers chiffres du SSN, précédemment appelé numéro de zone, en n'attribuant plus les numéros de zone à attribuer à des individus dans des états spécifiques ..__ Par conséquent, la liste des grands groupes est figée dans le temps et peut être utilisée pour valider les numéros de sécurité sociale émis avant la date de mise en œuvre de la randomisation. 999.
Nouvelles règles
http://en.wikipedia.org/wiki/Social_Security_number#Structure
Réponse précédente
Voici la description la plus complète de la composition d’un SSN que j’ai trouvée.
Depuis 2011, les numéros de sécurité sociale sont complètement randomisés ( http://www.socialsecurity.gov/employer/randomization.html )
Les seules règles réelles qui restent sont:
Réponse 5 ans après la question initiale en raison de modifications des règles de validation par la Social Security Administration . Il existe également des numéros spécifiques à invalider en fonction de ce link .
Conformément à ma réponse datant de près de deux ans, j'ai également omis isNumeric (ssn) car le champ est numérique et supprime déjà les caractères avant d'appeler la fonction validate.
// validate social security number with ssn parameter as string
function validateSSN(ssn) {
// find area number (1st 3 digits, no longer actually signifies area)
var area = parseInt(ssn.substring(0, 3));
return (
// 9 characters
ssn.length === 9 &&
// no set can start with zero
ssn.match(/^[1-9][0-9]{2}[1-9][0-9]{1}[1-9][0-9]{3}/) &&
// disallow Satan's minions from becoming residents of the US
area !== 666 &&
// it's over 900
area < 900 &&
// fun fact: some idiot boss put his secretary's ssn in wallets
// he sold, now it "belongs" to 40000 people
ssn !== '078051120' &&
// was used in an ad by the Social Security Administration
ssn !== '219099999'
);
}
Selon les informations mises à jour, il n'y a pas d'autres contrôles à effectuer.
Tout se trouve sur socialsecurity.gov : Système de numérotation , attributions , numéros les plus élevés mis à jour mensuellement.
Ceci est évidemment un ancien post, mais j'ai trouvé des moyens de le raccourcir. Il existe également quelques numéros spécifiques à invalider selon ce lien: http://www.snopes.com/business/taxes/woolworth.asp
Voici comment je l'ai fait. J'aurais pu utiliser des expressions rationnelles pour répéter des nombres, mais avec des expressions spécifiques pour invalider, nous pourrions aussi bien en ajouter à la liste (plus de 5) (plus de 5 invalideront quand même en raison de la validation du numéro de zone). J'ai également omis isNumeric (ssn) car le champ est numérique et supprime déjà les caractères avant d'appeler la fonction validate.
function validateSSN(ssn) {
// validate format (no all zeroes, length 9
if (!ssn.match(/^[1-9][0-9]{2}[1-9][0-9]{1}[1-9][0-9]{3}/)
|| ssn.length!=9) return false;
// validate area number (1st 3 digits)
var area=parseInt(ssn.substring(0, 3));
// standard railroad numbers (pre-1963)
if (area>649 && !(area>=700 && area<=728)) return false;
// disallow specific invalid number
if (ssn=='078051120' || // fun fact: some idiot boss put his
// secretary's ssn in wallets he sold,
// now this is 40000 people's ssn
ssn=='219099999' || // was used in an ad by the Social Security
// Administration
ssn=='123456789' || // although valid it's not yet assigned and
// you're not likely to meet the person who
// will get it
ssn=='123121234' || // probably is assigned to someone but more
// likely to find someone trying to fake a
// number (next is same)
ssn=='321214321' || // all the rest are likely potentially
// valid, but most likely these numbers are
// abused
ssn=='111111111' ||
ssn=='222222222' ||
ssn=='333333333' ||
ssn=='444444444' ||
ssn=='555555555') return false;
return true;
}
Je sais que c’est une vieille question, mais pour que les autres cherchent des réponses, j’ai pensé ajouter une fonction javascript rapide pour vérifier la validité d’un SSN donné.
function checkSSN() {
var inputSSN = #YourInput#,
ssnRegex = new RegExp("^(9[0-9][0-9]|666|000|078051120|219099999|123456789|123121234|321214321)|^([0-8][0-9][0-9]00)|^([0-8][0-9][0-9][0-9][0-9]000)$"),
repeats = /^(.)\1+$/;
//make sure we have 2 dashes in the input Social Security number
if( inputSSN.match(/./g).length === 2) {
//Once we have confirmed that there are the right number of dashes, remove them, and make sure that the resulting string is a number (you may or may not need this logic depending on the format of your input SSN.
inputSSN = inputSSN.replace(/-/g, "");
if(!isNaN(inputSSN)) {
//Test the input SSN against our regex to ensure that it doesn't contain any disqualifying combinations.
if(!ssnRegex.test(inputSSN)) {
//Make sure the input SSN isn't just a repeated number
if(!repeats.test(inputSSN)) {
//If it lands inside of this, we know it's a valid option for a social security number.
}
}
}
}
Pour la logique ssnRegex :
La première section traite si le SSN commence par un numéro 900-999, 666 000 ou l’un des SSN disqualifiants connus mentionné ci-dessus.
^ (9 [0-9] [0-9] | 666 | 000 | 078051120 | 219099999 | 123456789 | 123121234 | 321214321)
la deuxième section garantit que la partie à 2 chiffres n'est pas 00
^ ([0-8] [0-9] [0-9] 00)
La troisième section garantit que la dernière partie n'est pas 0000
^ ([0-8] [0-9] [0-9] [0-9] [0-9] 0000)
Nous vérifions en outre pour nous assurer qu'ils ont saisi un numéro et qu'ils n'utilisent pas simplement un nombre répété.
À partir de la randomisation des numéros de sécurité sociale post-911, les entrées de la série 900 et même de 666 sont maintenant des numéros potentiellement valides.
Les seules choses certaines à ce stade semblent être:
le premier groupe de 3 ne sera jamais 000
la paire du groupe intermédiaire ne sera jamais 00
et les quatre derniers ne seront jamais 0000
Vous pouvez effectuer des tests en effectuant d’abord des tests pour vous assurer que la valeur numérique de l’entrée est> = 1010001 [et <1000000000] (une valeur ssan de 001-01-0001 semble être la plus faible attribuée de manière légitime). Vous pouvez ensuite procéder à la vérification de 00 aux positions 4 et 5 et à 0000 dans les quatre dernières.
Voici ma version PHP
/**
* Validate SSN - must be in format AAA-GG-SSSS or AAAGGSSSS
*
* @param $ssn
* @return bool
*/
function validate_ssn($ssn) {
$ssnTrimmed = trim($ssn);
// Must be in format AAA-GG-SSSS or AAAGGSSSS
if ( ! preg_match("/^([0-9]{9}|[0-9]{3}-[0-9]{2}-[0-9]{4})$/", $ssnTrimmed)) {
return false;
}
// Split groups into an array
$ssnFormatted = (strlen($ssnTrimmed) == 9) ? preg_replace("/^([0-9]{3})([0-9]{2})([0-9]{4})$/", "$1-$2-$3", $ssnTrimmed) : $ssnTrimmed;
$ssn_array = explode('-', $ssnFormatted);
// number groups must follow these rules:
// * no single group can have all 0's
// * first group cannot be 666, 900-999
// * second group must be 01-99
// * third group must be 0001-9999
foreach ($ssn_array as $group) {
if ($group == 0) {
return false;
}
}
if ($ssn_array[0] == 666 || $ssn_array[0] > 899) {
return false;
}
return true;
}