{ "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 }