{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Vérification de numéros de Cartes Bleues, RIB (IBAN) et NIRPP (sécu)\n",
"\n",
"Ce petit notebook va implémenter les algorithmes de vérification des numéros de :\n",
"\n",
"- cartes bleues, sur $4\\times4$ chiffres, avec un chiffre de vérification,\n",
"- RIB (identifiant de compte, sur les IBAN), avec deux chiffres de vérifications,\n",
"- NIRPP (numéro de sécurité sociale en France), avec deux chiffres de vérifications.\n",
"\n",
"> J'avais déjà implementé les deux derniers, cf. ces scripts : [check_IBAN.py](https://bitbucket.org/lbesson/bin/src/master/check_IBAN.py), et [check_NIRPP.py](https://bitbucket.org/lbesson/bin/src/master/check_NIRPP.py).\n",
"\n",
"Si vous êtes curieux de l'aspect historique, [ce petit article](https://spectrum.ieee.org/tech-history/silicon-revolution/hans-peter-luhn-and-the-birth-of-the-hashing-algorithm) explique très bien les origines de ces chiffres de contrôles et de la [formule de Luhn](https://fr.wikipedia.org/wiki/Formule_de_Luhn)."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Je vais utiliser cette fonction plusieurs fois, qui permet de transformer une lettre 'A',...,'Z' en entier."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"def l_to_c(l):\n",
" try:\n",
" return str(int(l))\n",
" except ValueError:\n",
" return str(10 + ord(l.upper()) - ord('A'))"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"l = A --> c = 10\n",
"l = B --> c = 11\n",
"l = C --> c = 12\n",
"l = D --> c = 13\n",
"l = E --> c = 14\n",
"l = F --> c = 15\n",
"l = G --> c = 16\n",
"l = H --> c = 17\n",
"l = I --> c = 18\n",
"l = J --> c = 19\n",
"l = K --> c = 20\n",
"l = L --> c = 21\n",
"l = M --> c = 22\n",
"l = N --> c = 23\n",
"l = R --> c = 27\n",
"l = O --> c = 24\n",
"l = P --> c = 25\n",
"l = Q --> c = 26\n",
"l = R --> c = 27\n",
"l = S --> c = 28\n",
"l = T --> c = 29\n",
"l = U --> c = 30\n",
"l = V --> c = 31\n",
"l = W --> c = 32\n",
"l = X --> c = 33\n",
"l = Y --> c = 34\n",
"l = Z --> c = 35\n"
]
}
],
"source": [
"for l in 'ABCDEFGHIJKLMNROPQRSTUVWXYZ':\n",
" print(\"l = {} --> c = {}\".format(l, l_to_c(l)))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Cartes Bleues\n",
"\n",
"- Références : https://www.hellolife.fr/article/a-quoi-correspondent-les-chiffres-sur-ma-carte-bancaire_a466/1 et https://fr.wikipedia.org/wiki/Carte_de_paiement#Num%C3%A9ro_de_carte_bancaire et https://fr.wikipedia.org/wiki/Formule_de_Luhn\n",
"- Exemple :\n",
""
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"exemple_cb = \"4970 1012 3456 7890\" # pas valide"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"D'abord l'algorithme de Luhn :"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [],
"source": [
"def verifie_Luhn(numeros):\n",
" numeros = numeros.replace(' ', '')\n",
" nb_chiffres = len(numeros)\n",
" parite = nb_chiffres % 2\n",
" chiffres = [int(l_to_c(l)) for l in numeros]\n",
" somme = chiffres[nb_chiffres - 1]\n",
" for i in range(nb_chiffres - 2, -1, -1):\n",
" chiffre = chiffres[i]\n",
" if i % 2 == parite:\n",
" chiffre *= 2\n",
" if chiffre > 9:\n",
" chiffre -= 9\n",
" somme += chiffre\n",
" return (somme % 10) == 0"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"verifie_Luhn('972 487 086')"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"verifie_Luhn('972 487 081')\n",
"verifie_Luhn('972 487 082')\n",
"verifie_Luhn('972 487 087')"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"verifie_Luhn(exemple_cb)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Ensuite la vérification pour un numéro de carte bleue :"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [],
"source": [
"def verifie_cb(cb):\n",
" print(\"\\nVérification du numéro de CB '%s'...\" % cb)\n",
" check = verifie_Luhn(cb)\n",
" if check:\n",
" print(\"OK '%s' semble être un numéro de CB valide.\" % cb)\n",
" else:\n",
" print(\"[ATTENTION] PAS OK '%s' semble ne pas être un numéro de CB valide!\" % cb)\n",
" return check"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exemples"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Vérification du numéro de CB '4970 1012 3456 7890'...\n",
"[ATTENTION] PAS OK '4970 1012 3456 7890' semble ne pas être un numéro de CB valide!\n"
]
},
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"verifie_cb(exemple_cb)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Avec un autre faux numéro mais conçu pour être vrai :"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Vérification du numéro de CB '4976 5301 7218 3533'...\n",
"OK '4976 5301 7218 3533' semble être un numéro de CB valide.\n"
]
},
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"verifie_cb(\"4976 5301 7218 3533\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## RIB/IBAN\n",
"\n",
"- Référence : https://fr.wikipedia.org/wiki/International_Bank_Account_Number#Algorithme_de_v.C3.A9rification_de_l.27IBAN\n",
"- Exemple :\n",
""
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [],
"source": [
"exemple_iban = \"FR76 1254 8029 9838 3759 0150 071\""
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [],
"source": [
"def verifie_iban(iban):\n",
" print(\"\\nVérification du nombre IBAN '%s'...\" % iban)\n",
" ib = iban.replace(' ', '')\n",
" ib = ib[4:] + ib[:4]\n",
" print(\" De longueur\", len(ib))\n",
" i = int(''.join(l_to_c(l) for l in ib))\n",
" check = (i % 97) == 1\n",
" if check:\n",
" print(\"OK '%s' semble être un nombre IBAN valide.\" % iban)\n",
" else:\n",
" print(\"[ATTENTION] PAS OK '%s' semble ne pas être un nombre IBAN valide!\" % iban)\n",
" return check"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exemples"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Compte français"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Vérification du nombre IBAN 'FR76 1254 8029 9838 3759 0150 071'...\n",
" De longueur 27\n",
"OK 'FR76 1254 8029 9838 3759 0150 071' semble être un nombre IBAN valide.\n"
]
},
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"verifie_iban(exemple_iban)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Compte anglais"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Vérification du nombre IBAN 'GB87 BARC 2065 8244 9716 55'...\n",
" De longueur 22\n",
"OK 'GB87 BARC 2065 8244 9716 55' semble être un nombre IBAN valide.\n"
]
},
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"verifie_iban(\"GB87 BARC 2065 8244 9716 55\")"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Vérification du nombre IBAN 'GB87 BARC 2065 8244 9716 51'...\n",
" De longueur 22\n",
"[ATTENTION] PAS OK 'GB87 BARC 2065 8244 9716 51' semble ne pas être un nombre IBAN valide!\n"
]
},
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"verifie_iban(\"GB87 BARC 2065 8244 9716 51\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"#### Compte belge"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Vérification du nombre IBAN 'BE43 0689 9999 9501'...\n",
" De longueur 16\n",
"OK 'BE43 0689 9999 9501' semble être un nombre IBAN valide.\n"
]
},
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"verifie_iban(\"BE43 0689 9999 9501\")"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Vérification du nombre IBAN 'BE43 0689 9999 9500'...\n",
" De longueur 16\n",
"[ATTENTION] PAS OK 'BE43 0689 9999 9500' semble ne pas être un nombre IBAN valide!\n"
]
},
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"verifie_iban(\"BE43 0689 9999 9500\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## NIRPP\n",
"- Référence : https://fr.wikipedia.org/wiki/Num%C3%A9ro_de_s%C3%A9curit%C3%A9_sociale_en_France#cite_note-8\n",
"- Exemple :\n",
""
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [],
"source": [
"exemple_nirpp = \"2 69 05 49 588 157 80\""
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [],
"source": [
"length_checksum = 2\n",
"\n",
"def verifie_nirpp(nirpp, length_checksum=length_checksum):\n",
" print(\"\\nVérification du nombre NIRPP '%s' ...\" % nirpp)\n",
" ib = nirpp.replace(' ', '')\n",
" checksum = int(ib[-length_checksum:])\n",
" ib = ib[:-length_checksum]\n",
" print(\" De longueur\", len(ib))\n",
" num_nirpp = int(''.join(l_to_c(l) for l in ib))\n",
" print(\" De somme de contrôle num_nirpp =\", num_nirpp)\n",
" print(\" Module à 97 =\", (97 - (num_nirpp % 97)))\n",
" print(\" Et la somme de contrôle attendue était\", checksum)\n",
" check = (97 - (num_nirpp % 97)) == checksum\n",
" if check:\n",
" print(\"OK '%s' semble être un nombre NIRPP valide.\" % nirpp)\n",
" else:\n",
" print(\"[ATTENTION] PAS OK '%s' semble ne pas être un nombre NIRPP valide!\" % nirpp)\n",
" return check"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exemples"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Vérification du nombre NIRPP '2 69 05 49 588 157 80' ...\n",
" De longueur 13\n",
" De somme de contrôle num_nirpp = 2690549588157\n",
" Module à 97 = 80\n",
" Et la somme de contrôle attendue était 80\n",
"OK '2 69 05 49 588 157 80' semble être un nombre NIRPP valide.\n"
]
},
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"verifie_nirpp(exemple_nirpp)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Bonus : affichage d'un NIRPP\n",
"- Référence : https://fr.wikipedia.org/wiki/Num%C3%A9ro_de_s%C3%A9curit%C3%A9_sociale_en_France#Signification_des_chiffres_du_NIR\n",
"\n",
"Il suffit de récupérer les informations de chaque morceau du code NIRPP, et les stocker comme ça :"
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {},
"outputs": [],
"source": [
"information_nirpp = {\n",
" (0, 1): {\n",
" \"meaning\": \"sexe\",\n",
" \"mapping\": {\n",
" \"1\": \"homme\",\n",
" \"2\": \"femme\",\n",
" \"3\": \"personne étrangère de sexe masculin en cours d'immatriculation en France\",\n",
" \"4\": \"personne étrangère de sexe féminin en cours d'immatriculation en France\"\n",
" }\n",
" },\n",
" (1, 2): {\n",
" \"meaning\": \"deux derniers chiffres de l'année de naissance\",\n",
" \"mapping\": {\n",
" # DONE nothing to do for this information\n",
" }\n",
" },\n",
" (3, 2): {\n",
" \"meaning\": \"mois de naissance\",\n",
" \"mapping\": {\n",
" \"01\": \"janvier\",\n",
" \"02\": \"février\",\n",
" \"03\": \"mars\",\n",
" \"04\": \"avril\",\n",
" \"05\": \"mai\",\n",
" \"06\": \"juin\",\n",
" \"07\": \"juillet\",\n",
" \"08\": \"août\",\n",
" \"09\": \"septembre\",\n",
" \"10\": \"octobre\",\n",
" \"11\": \"novembre\",\n",
" \"12\": \"décembre\",\n",
" }\n",
" },\n",
" # Only case A : TODO implement case B and C\n",
" (5, 2): {\n",
" \"meaning\": \"département de naissance métropolitain\",\n",
" \"mapping\": { # Cf. http://www.insee.fr/fr/methodes/nomenclatures/cog/documentation.asp\n",
" \"01\": \"Ain\",\n",
" \"02\": \"Aisne\",\n",
" \"03\": \"Allier\",\n",
" \"04\": \"Alpes-de-Haute-Provence\",\n",
" \"05\": \"Hautes-Alpes\",\n",
" \"06\": \"Alpes-Maritimes\",\n",
" \"07\": \"Ardèche\",\n",
" \"08\": \"Ardennes\",\n",
" \"09\": \"Ariège\",\n",
" \"10\": \"Aube\",\n",
" \"11\": \"Aude\",\n",
" \"12\": \"Aveyron\",\n",
" \"13\": \"Bouches-du-Rhône\",\n",
" \"14\": \"Calvados\",\n",
" \"15\": \"Cantal\",\n",
" \"16\": \"Charente\",\n",
" \"17\": \"Charente-Maritime\",\n",
" \"18\": \"Cher\",\n",
" \"19\": \"Corrèze\",\n",
" \"2A\": \"Corse-du-Sud\",\n",
" \"2B\": \"Haute-Corse\",\n",
" \"21\": \"Côte-d'Or\",\n",
" \"22\": \"Côtes-d'Armor\",\n",
" \"23\": \"Creuse\",\n",
" \"24\": \"Dordogne\",\n",
" \"25\": \"Doubs\",\n",
" \"26\": \"Drôme\",\n",
" \"27\": \"Eure\",\n",
" \"28\": \"Eure-et-Loir\",\n",
" \"29\": \"Finistère\",\n",
" \"30\": \"Gard\",\n",
" \"31\": \"Haute-Garonne\",\n",
" \"32\": \"Gers\",\n",
" \"33\": \"Gironde\",\n",
" \"34\": \"Hérault\",\n",
" \"35\": \"Ille-et-Vilaine\",\n",
" \"36\": \"Indre\",\n",
" \"37\": \"Indre-et-Loire\",\n",
" \"38\": \"Isère\",\n",
" \"39\": \"Jura\",\n",
" \"40\": \"Landes\",\n",
" \"41\": \"Loir-et-Cher\",\n",
" \"42\": \"Loire\",\n",
" \"43\": \"Haute-Loire\",\n",
" \"44\": \"Loire-Atlantique\",\n",
" \"45\": \"Loiret\",\n",
" \"46\": \"Lot\",\n",
" \"47\": \"Lot-et-Garonne\",\n",
" \"48\": \"Lozère\",\n",
" \"49\": \"Maine-et-Loire\",\n",
" \"50\": \"Manche\",\n",
" \"51\": \"Marne\",\n",
" \"52\": \"Haute-Marne\",\n",
" \"53\": \"Mayenne\",\n",
" \"54\": \"Meurthe-et-Moselle\",\n",
" \"55\": \"Meuse\",\n",
" \"56\": \"Morbihan\",\n",
" \"57\": \"Moselle\",\n",
" \"58\": \"Nièvre\",\n",
" \"59\": \"Nord\",\n",
" \"60\": \"Oise\",\n",
" \"61\": \"Orne\",\n",
" \"62\": \"Pas-de-Calais\",\n",
" \"63\": \"Puy-de-Dôme\",\n",
" \"64\": \"Pyrénées-Atlantiques\",\n",
" \"65\": \"Hautes-Pyrénées\",\n",
" \"66\": \"Pyrénées-Orientales\",\n",
" \"67\": \"Bas-Rhin\",\n",
" \"68\": \"Haut-Rhin\",\n",
" \"69\": \"Rhône\",\n",
" \"70\": \"Haute-Saône\",\n",
" \"71\": \"Saône-et-Loire\",\n",
" \"72\": \"Sarthe\",\n",
" \"73\": \"Savoie\",\n",
" \"74\": \"Haute-Savoie\",\n",
" \"75\": \"Paris\",\n",
" \"76\": \"Seine-Maritime\",\n",
" \"77\": \"Seine-et-Marne\",\n",
" \"78\": \"Yvelines\",\n",
" \"79\": \"Deux-Sèvres\",\n",
" \"80\": \"Somme\",\n",
" \"81\": \"Tarn\",\n",
" \"82\": \"Tarn-et-Garonne\",\n",
" \"83\": \"Var\",\n",
" \"84\": \"Vaucluse\",\n",
" \"85\": \"Vendée\",\n",
" \"86\": \"Vienne\",\n",
" \"87\": \"Haute-Vienne\",\n",
" \"88\": \"Vosges\",\n",
" \"89\": \"Yonne\",\n",
" \"90\": \"Territoire de Belfort\",\n",
" \"91\": \"Essonne\",\n",
" \"92\": \"Hauts-de-Seine\",\n",
" \"93\": \"Seine-Saint-Denis\",\n",
" \"94\": \"Val-de-Marne\",\n",
" \"95\": \"Val-d'Oise\",\n",
" # TODO support these too\n",
" \"971\": \"Guadeloupe\",\n",
" \"972\": \"Martinique\",\n",
" \"973\": \"Guyane\",\n",
" \"974\": \"La Réunion\",\n",
" \"975\": \"Saint-Pierre-et-Miquelon\",\n",
" \"976\": \"Mayotte\",\n",
" \"977\": \"Saint-Barthélemy\",\n",
" \"978\": \"Saint-Martin\",\n",
" \"984\": \"Terres australes et antarctiques françaises\",\n",
" \"986\": \"Wallis-et-Futuna\",\n",
" \"987\": \"Polynésie française\",\n",
" \"988\": \"Nouvelle-Calédonie\",\n",
" \"989\": \"Île de Clipperton\"\n",
" }\n",
" },\n",
" (7, 3): {\n",
" \"meaning\": \"code officiel de la commune de naissance\",\n",
" \"mapping\": { # TODO\n",
" }\n",
" },\n",
" (10, 3): {\n",
" \"meaning\": \"numéro d’ordre de la naissance dans le mois et la commune (ou le pays)\",\n",
" \"mapping\": {\n",
" # DONE nothing to do for this information\n",
" }\n",
" }\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Pour les villes, on a besoin d'une base de donnée plus grande. J'ai récupéré [ce fichier](https://bitbucket.org/lbesson/bin/src/master/comsimp2016.txt) sur le site de l'INSEE (lien mort)."
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"comsimp2016.txt\t\t Exemple_CB.jpg Exemple_RIB.jpg\r\n",
"Exemple_CarteVitale.jpg Exemple_IMEI.jpg\r\n"
]
}
],
"source": [
"!ls data/"
]
},
{
"cell_type": "code",
"execution_count": 23,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" 35886 40952 1685861 data/comsimp2016.txt\r\n"
]
}
],
"source": [
"!wc data/comsimp2016.txt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Il ressemble à ça :"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"CDC,CHEFLIEU,REG,DEP,COM,AR,CT,TNCC,ARTMAJ,NCC,ARTMIN,NCCENR\r\n",
"0,0,84,01,001,2,08,5,(L') ABERGEMENT-CLEMENCIAT,(L') Abergement-Clémenciat\r\n",
"0,0,84,01,002,1,01,5,(L') ABERGEMENT-DE-VAREY,(L') Abergement-de-Varey\r\n",
"0,1,84,01,004,1,01,1,AMBERIEU-EN-BUGEY,Ambérieu-en-Bugey\r\n",
"0,0,84,01,005,2,22,1,AMBERIEUX-EN-DOMBES,Ambérieux-en-Dombes\r\n",
"0,0,84,01,006,1,04,1,AMBLEON,Ambléon\r\n",
"0,0,84,01,007,1,01,1,AMBRONAY,Ambronay\r\n",
"0,0,84,01,008,1,01,1,AMBUTRIX,Ambutrix\r\n",
"0,0,84,01,009,1,04,1,ANDERT-ET-CONDON,Andert-et-Condon\r\n",
"0,0,84,01,010,1,10,1,ANGLEFORT,Anglefort\r\n"
]
}
],
"source": [
"!head data/comsimp2016.txt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Briançon est bien dans la liste :"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"1,2,93,05,023,1,98,0,BRIANCON,Briançon\r\n",
"0,0,93,06,024,1,11,0,BRIANCONNET,Briançonnet\r\n"
]
}
],
"source": [
"!grep \"BRIANCON\" data/comsimp2016.txt"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Allons-y :"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [],
"source": [
"import subprocess\n",
"length_checksum = 2\n",
"\n",
"\n",
"def pprint_nirpp(nirpp, length_checksum=length_checksum):\n",
" print(\"\\nAffichage d'informations contenues dans le numéro NIRPP '%s' ...\" % nirpp)\n",
" nirpp = nirpp.replace(' ', '')\n",
" ib = nirpp[:-length_checksum]\n",
" # Printing\n",
" for (i, l) in sorted(information_nirpp):\n",
" n = nirpp[i: i + l]\n",
" info = information_nirpp[(i, l)]\n",
" if n in info[\"mapping\"]:\n",
" explain = \"\\\"{}\\\"\".format(info[\"mapping\"][n])\n",
" else:\n",
" explain = n\n",
" # For towns, durty hack to extract the town from the INSEE database\n",
" if i == 7:\n",
" try:\n",
" args = [\n",
" \"grep\", \"--\", \"',{},{},'\".format(\n",
" nirpp[5: 5 + 2],\n",
" nirpp[7: 7 + 3]\n",
" ),\n",
" \"data/comsimp2016.txt\",\n",
" \"|\", \"cut\", \"-d,\", \"-f10\"\n",
" ]\n",
" command = ' '.join(args)\n",
" # print(\"Executing subprocess.check_output to \\\"{}\\\"\".format(command))\n",
" explain = subprocess.check_output(command, shell=True)\n",
" explain = explain[:-1].decode()\n",
" # print(\"explain =\", explain)\n",
" explain = \"{} (code {})\".format(explain, nirpp[7: 7 + 3])\n",
" except Exception as e:\n",
" # print(\"e =\", e)\n",
" explain = n\n",
" print(\"- Le nombre '{}' (indice {}:{}) signifie:\\n\\t\\\"{}\\\" : \\t{}\".format(\n",
" n, i, i + l, info[\"meaning\"], explain)\n",
" )"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Affichage d'informations contenues dans le numéro NIRPP '2 69 05 49 588 157 80' ...\n",
"- Le nombre '2' (indice 0:1) signifie:\n",
"\t\"sexe\" : \t\"femme\"\n",
"- Le nombre '69' (indice 1:3) signifie:\n",
"\t\"deux derniers chiffres de l'année de naissance\" : \t69\n",
"- Le nombre '05' (indice 3:5) signifie:\n",
"\t\"mois de naissance\" : \t\"mai\"\n",
"- Le nombre '49' (indice 5:7) signifie:\n",
"\t\"département de naissance métropolitain\" : \t\"Maine-et-Loire\"\n",
"- Le nombre '588' (indice 7:10) signifie:\n",
"\t\"code officiel de la commune de naissance\" : \t (code 588)\n",
"- Le nombre '157' (indice 10:13) signifie:\n",
"\t\"numéro d’ordre de la naissance dans le mois et la commune (ou le pays)\" : \t157\n"
]
}
],
"source": [
"pprint_nirpp(exemple_nirpp)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Avec un exemple assez proche de mon numéro de sécurité sociale (modifié) :"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Affichage d'informations contenues dans le numéro NIRPP '1 93 01 05 023 122 23' ...\n",
"- Le nombre '1' (indice 0:1) signifie:\n",
"\t\"sexe\" : \t\"homme\"\n",
"- Le nombre '93' (indice 1:3) signifie:\n",
"\t\"deux derniers chiffres de l'année de naissance\" : \t93\n",
"- Le nombre '01' (indice 3:5) signifie:\n",
"\t\"mois de naissance\" : \t\"janvier\"\n",
"- Le nombre '05' (indice 5:7) signifie:\n",
"\t\"département de naissance métropolitain\" : \t\"Hautes-Alpes\"\n",
"- Le nombre '023' (indice 7:10) signifie:\n",
"\t\"code officiel de la commune de naissance\" : \tBriançon (code 023)\n",
"- Le nombre '122' (indice 10:13) signifie:\n",
"\t\"numéro d’ordre de la naissance dans le mois et la commune (ou le pays)\" : \t122\n"
]
}
],
"source": [
"pprint_nirpp(\"1 93 01 05 023 122 23\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## IMEI\n",
"Les numéros d'identification des téléphones portables ([les IMEI](https://fr.wikipedia.org/wiki/International_Mobile_Equipment_Identity#Structure)) terminent aussi par un chiffre de contrôle, qui utilise aussi la [formule de Luhn](https://fr.wikipedia.org/wiki/Formule_de_Luhn).\n",
"Je termine ce notebook en implémentant aussi cette vérification.\n",
"\n",
""
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [],
"source": [
"exemple_imei = \"448674 52 897641 0\" # avant 2014, 6-2-6-1"
]
},
{
"cell_type": "code",
"execution_count": 30,
"metadata": {},
"outputs": [],
"source": [
"def verifie_imei(imei):\n",
" print(\"\\nVérification du numéro IMEI '%s'...\" % imei)\n",
" check = verifie_Luhn(imei)\n",
" if check:\n",
" print(\"OK '%s' semble être un numéro IMEI valide.\" % imei)\n",
" else:\n",
" print(\"[ATTENTION] PAS OK '%s' semble ne pas être un numéro IMEI valide!\" % imei)\n",
" return check"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Vérification du numéro IMEI '448674528976410'...\n",
"OK '448674528976410' semble être un numéro IMEI valide.\n"
]
},
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"verifie_imei(exemple_imei)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Exemples"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [],
"source": [
"exemple_imei = \"448674 52 897641 1\""
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Vérification du numéro IMEI '448674528976411'...\n",
"[ATTENTION] PAS OK '448674528976411' semble ne pas être un numéro IMEI valide!\n"
]
},
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"verifie_imei(exemple_imei)"
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [],
"source": [
"exemple_imei = \"468674 52 897641 0\""
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Vérification du numéro IMEI '468674528976410'...\n",
"[ATTENTION] PAS OK '468674528976410' semble ne pas être un numéro IMEI valide!\n"
]
},
{
"data": {
"text/plain": [
"False"
]
},
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"verifie_imei(exemple_imei)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Avec un IMEI semblable à celui d'un de mes anciens téléphones :"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Vérification du numéro IMEI '35569508 262195 2'...\n",
"OK '35569508 262195 2' semble être un numéro IMEI valide.\n"
]
},
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"mon_faux_imei_1 = \"35569508 262195 2\"\n",
"\n",
"verifie_imei(mon_faux_imei_1)"
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"\n",
"Vérification du numéro IMEI '35569508 283295 5'...\n",
"OK '35569508 283295 5' semble être un numéro IMEI valide.\n"
]
},
{
"data": {
"text/plain": [
"True"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"mon_faux_imei_2 = \"35569508 283295 5\"\n",
"\n",
"verifie_imei(mon_faux_imei_2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Conclusion\n",
"\n",
"Voilà, c'est tout pour aujourd'hui !\n",
"\n",
"> Allez lire [ici pour voir mes autres notebooks](https://GitHub.com/Naereen/notebooks)."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.6.3"
},
"toc": {
"colors": {
"hover_highlight": "#DAA520",
"running_highlight": "#FF0000",
"selected_highlight": "#FFD700"
},
"moveMenuLeft": true,
"nav_menu": {
"height": "279px",
"width": "251px"
},
"navigate_menu": true,
"number_sections": true,
"sideBar": true,
"threshold": 4,
"toc_cell": false,
"toc_position": {
"height": "554px",
"left": "0px",
"right": "1228px",
"top": "173.5px",
"width": "212px"
},
"toc_section_display": "block",
"toc_window_display": true
},
"varInspector": {
"cols": {
"lenName": 16,
"lenType": 16,
"lenVar": 40
},
"kernels_config": {
"python": {
"delete_cmd_postfix": "",
"delete_cmd_prefix": "del ",
"library": "var_list.py",
"varRefreshCmd": "print(var_dic_list())"
},
"r": {
"delete_cmd_postfix": ") ",
"delete_cmd_prefix": "rm(",
"library": "var_list.r",
"varRefreshCmd": "cat(var_dic_list()) "
}
},
"types_to_exclude": [
"module",
"function",
"builtin_function_or_method",
"instance",
"_Feature"
],
"window_display": false
}
},
"nbformat": 4,
"nbformat_minor": 2
}