Exemples pratiques sur les outils LINO-PIMO
Générer le NIR avec pimo
Le NIR plus communément appelé numéro de sécurité sociale est un numéro unique attribué par l'INSEE dès la naissance.
Il est composé de 15 chiffres :
n°1 | n°2 | n°3 | n°4 | n°5 | clé |
---|---|---|---|---|---|
Sexe | Année de naissance | Mois de naissance | Lieu de naissance | Numéro d'ordre de naissance | Clé de contrôle |
X | XX | XX | XXXXX | XXX | XX |
1ère méthode : regex
La 1ère méthode consiste à générer le numéro de sécurité sociale sans se préoccuper de connaître les informations liées à la personne (sexe, année de naissance, ...).
masking.yml
version: "1"
seed: 42
masking:
- selector:
jsonpath: "VALEUR_NIR"
masks:
- add-transient: ""
- regex: "(1|2)[0-9]{2}(0[1-9]|1[0-2])((0[1-9]|[1-8][0-9]|9[0-5])([0-8][0-9]{2}|90[0-9]))[0-9]{3}"
# Partie Clé du NIR
# Clé NIR = 97 - ( ( Valeur numérique du NIR ) modulo 97 )
- selector:
jsonpath: "CLE_NIR"
mask:
add-transient: '{{ sub 97 (mod (int64 .VALEUR_NIR) 97)}}'
- selector:
jsonpath: "NIR"
mask:
add: '{{(toString .VALEUR_NIR)}}{{if eq (len .CLE_NIR) 1}}0{{(toString .CLE_NIR)}}{{else}}{{(toString .CLE_NIR)}}{{end}}'
pimo -c masking.yml --empty-input -r 5
{"NIR":"271067590908916"}
{"NIR":"148029053117547"}
{"NIR":"251079456401559"}
{"NIR":"198109213274847"}
{"NIR":"161113883742960"}
2ème méthode : enchaînement de masking
La 2ème méthode consiste, cette fois-ci, à générer le NIR en gardant la cohérence entre les informations d'une personne et son numéro de sécurité sociale.
masking.yml
version: "2"
seed: 42
masking:
#----------------------------------------------------------
# Partie n°1 + n°2 + n°3 du NIR
- selector :
jsonpath: "SEXE"
masks:
- add: ""
- randomChoice:
- "M"
- "F"
- selector :
jsonpath: "DATE_NAISSANCE"
masks:
- add: ""
- randDate:
dateMin: "1960-01-01T00:00:00Z"
dateMax: "2002-12-31T00:00:00Z"
- dateParser:
outputFormat: "02/01/2006"
#----------------------------------------------------------
#----------------------------------------------------------
# Partie n°4 + n°5 du NIR
- selector:
jsonpath: "ADRESSE_BRUTE_NAISSANCE"
masks:
- add-transient: ""
- randomChoiceInUri: "file://adresse.csv"
- selector:
jsonpath: "CODE_INSEE_NAISSANCE"
masks:
- add: '{{$a := split ";" (toString .ADRESSE_BRUTE_NAISSANCE) }}{{$a._6}}'
- selector:
jsonpath: "ORDRE_NAISSANCE"
masks:
- add: ""
- regex: "[0-9]{3}"
- selector:
jsonpath: "FIN_NIR"
masks:
- add-transient: "{{(toString .CODE_INSEE_NAISSANCE)}}{{(toString .ORDRE_NAISSANCE)}}"
#----------------------------------------------------------
#----------------------------------------------------------
# Partie Valeur du NIR
- selector:
jsonpath: "VALEUR_NIR"
masks:
- add-transient: '{{if eq .SEXE "M" }}1{{else}}2{{end}}{{substr 8 10 (toString .DATE_NAISSANCE)}}{{substr 3 5 (toString .DATE_NAISSANCE)}}{{.FIN_NIR}}'
#----------------------------------------------------------
#----------------------------------------------------------
# Partie Clé du NIR
# Clé NIR = 97 - ( ( Valeur numérique du NIR ) modulo 97 )
- selector:
jsonpath: "CLE_NIR"
masks:
- add-transient: '{{ sub 97 (mod (int64 .VALEUR_NIR) 97)}}'
#----------------------------------------------------------
#----------------------------------------------------------
# Totalité du NIR
- selector:
jsonpath: "NIR"
masks:
- add: '{{(toString .VALEUR_NIR)}}{{if eq (len .CLE_NIR) 1}}0{{(toString .CLE_NIR)}}{{else}}{{(toString .CLE_NIR)}}{{end}}'
#----------------------------------------------------------
Ci-dessous les 5 premières lignes du fichier adresse.csv
:
id | id_fantoir | numero | rep | nom_voie | code_postal | code_insee | nom_commune | code_insee_ancienne_commune | nom_ancienne_commune | x | y | lon | lat | alias | nom_ld | libelle_acheminement | nom_afnor | source_position | source_nom_voie |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
59001_nhsgdi_00001 | 1 | Chemin Hem Lenglet | 59268 | 59001 | Abancourt | 715617.46 | 7015153.4 | 3.218633 | 50.234188 | ABANCOURT | CHEMIN HEM LENGLET | arcep | arcep | ||||||
59001_0260_00001 | 59001_0260 | 1 | Rue Verte | 59268 | 59001 | Abancourt | 715163.83 | 7015088.68 | 3.21228 | 50.233618 | ABANCOURT | RUE VERTE | inconnue | inconnue | |||||
59001_0260_00003 | 59001_0260 | 3 | Rue Verte | 59268 | 59001 | Abancourt | 715152.71 | 7015104.02 | 3.212125 | 50.233756 | ABANCOURT | RUE VERTE | inconnue | inconnue | |||||
59001_0260_00004 | 59001_0260 | 4 | Rue Verte | 59268 | 59001 | Abancourt | 715121.01 | 7015153.72 | 3.211683 | 50.234203 | ABANCOURT | RUE VERTE | inconnue | inconnue | |||||
59001_0260_00005 | 59001_0260 | 5 | Rue Verte | 59268 | 59001 | Abancourt | 715140.52 | 7015123.37 | 3.211955 | 50.23393 | ABANCOURT | RUE VERTE | inconnue | inconnue |
pimo -c masking.yml --empty-input -r 5
{"SEXE":"F","DATE_NAISSANCE":"12/12/1990","CODE_INSEE_NAISSANCE":"59001","ORDRE_NAISSANCE":"384","NIR":"190125900138430"}
{"SEXE":"M","DATE_NAISSANCE":"01/02/1994","CODE_INSEE_NAISSANCE":"59001","ORDRE_NAISSANCE":"071","NIR":"294025900107134"}
{"SEXE":"F","DATE_NAISSANCE":"23/02/2000","CODE_INSEE_NAISSANCE":"59001","ORDRE_NAISSANCE":"634","NIR":"100025900163453"}
{"SEXE":"F","DATE_NAISSANCE":"11/02/1986","CODE_INSEE_NAISSANCE":"59001","ORDRE_NAISSANCE":"379","NIR":"186025900137971"}
{"SEXE":"F","DATE_NAISSANCE":"21/08/1972","CODE_INSEE_NAISSANCE":"59001","ORDRE_NAISSANCE":"439","NIR":"172085900143917"}
Générer une adresse mail avec pimo
masking.yml
version: "1"
seed: 0
masking:
# ----------------------- NOM -----------------------
- selector :
jsonpath: "NOM"
masks:
- add-transient: "M"
- randomChoiceInUri: "pimo://surnameFR"
- template: "{{.NOM | NoAccent | lower}}"
# ----------------------- PRÉNOM -----------------------
- selector :
jsonpath: "PRENOM"
masks:
- add-transient: ""
- randomChoiceInUri: "pimo://nameFR"
- template: "{{.PRENOM | NoAccent | lower}}"
#---------------------------- EMAIL ----------------------
- selector:
jsonpath: "MAIL"
masks:
- add: '{{- .NOM | replace " " ""}}.{{- .PRENOM | replace " " ""}}@yopmail.com'
pimo -c masking.yml --empty-input -r 5
{"MAIL":"girard.celiane@yopmail.com"}
{"MAIL":"henry.mickael@yopmail.com"}
{"MAIL":"caron.dalhia@yopmail.com"}
{"MAIL":"martin.veronique@yopmail.com"}
{"MAIL":"gauthier.chantal@yopmail.com"}
Masquer des données imbriquées avec pimo
Prenons comme exemple le fichier suivant composé d'une liste de dossier. Chaque dossier ayant un identifiant et une liste de personnes concernées par ce dossier :
input.json
{
"dossier": [
{
"identifiant": "AZ18-45B12",
"personnes": [
{
"nom": "Martin",
"prénom": "Veronique",
"email": "martin.veronique@mail.com"
},
{
"nom": "Robert",
"prénom": "Joe",
"email": "rober.joe@mail.com"
}
]
},
{
"identifiant": "JL34-28C79",
"personnes": [
{
"nom": "Alain",
"prénom": "Mercier",
"email": "alain.mercier@mail.com"
},
{
"nom": "Florian",
"prénom": "Roger",
"email": "florian.roger@mail.com"
}
]
}
]
}
Pour masquer les données sensibles de ce fichier nous utilisons le fichier de configuration suivant:
masking.yml
version: "1"
seed: 42
masking:
- selector:
jsonpath: "dossier.identifiant"
mask:
regex: "[A-Z]{2}[0-9]{2}-[0-9]{2}[A-Z][0-9]{2}"
- selector:
jsonpath: "dossier.personnes"
mask:
pipe:
masking:
- selector:
jsonpath: "nom"
mask:
randomChoiceInUri: "pimo://surnameFR"
- selector:
jsonpath: "prénom"
mask:
randomChoiceInUri: "pimo://nameFR"
- selector:
jsonpath: "email"
mask:
template: "{{.nom | NoAccent | lower}}.{{.prénom | NoAccent | lower}}@mail.com"
pimo -c masking.yml < input.json | jq
{
"dossier": [
{
"identifiant": "RS03-09T37",
"personnes": [
{
"nom": "Fournier",
"prénom": "Orianne",
"email": "fournier.orianne@mail.com"
},
{
"nom": "Leclerc",
"prénom": "Remi",
"email": "leclerc.remi@mail.com"
}
]
},
{
"identifiant": "FP37-33R33",
"personnes": [
{
"nom": "Vidal",
"prénom": "Michaël",
"email": "vidal.michael@mail.com"
},
{
"nom": "Bertrand",
"prénom": "Line",
"email": "bertrand.line@mail.com"
}
]
}
]
}
Générer un identifiant avec pimo
Si l'on reprend le fichier masking.yml
de l'exemple précédent, on peut le modifier légèrement en remplaçant le masque regex par le masque transcode qui permet de produire une chaîne de caractère aléatoire (en préservant le format) et ainsi masquer l'identifiant.
masking.yml
version: "2"
seed: 42
masking:
- selector:
jsonpath: "dossier.identifiant"
mask:
transcode: {}
- selector:
jsonpath: "dossier.personnes"
mask:
pipe:
masking:
- selector:
jsonpath: "nom"
mask:
randomChoiceInUri: "pimo://surnameFR"
- selector:
jsonpath: "prénom"
mask:
randomChoiceInUri: "pimo://nameFR"
- selector:
jsonpath: "email"
mask:
template: "{{.nom | NoAccent | lower}}.{{.prénom | NoAccent | lower}}@mail.com"
pimo -c masking.yml < input.json | jq
{
"dossier": [
{
"identifiant": "PH30-37U04",
"personnes": [
{
"nom": "Fournier",
"prénom": "Orianne",
"email": "fournier.orianne@mail.com"
},
{
"nom": "Leclerc",
"prénom": "Remi",
"email": "leclerc.remi@mail.com"
}
]
},
{
"identifiant": "FX70-68A25",
"personnes": [
{
"nom": "Vidal",
"prénom": "Michaël",
"email": "vidal.michael@mail.com"
},
{
"nom": "Bertrand",
"prénom": "Line",
"email": "bertrand.line@mail.com"
}
]
}
]
}
Un moyen de générer un identifiant est d'ajouter un nouveau champ id contenant la valeur d'un identifiant, et ensuite d'utiliser le masque transcode qui va reproduire aléatoirement des chaînes de caractères en copiant le format de l'identifiant ajouté précédemment.
masking2.yml
version: "1"
seed: 42
masking:
- selector:
jsonpath: "id"
masks:
- add: "1040-AZ-52"
- transcode: {}
pimo -c masking2.yml --empty-input -r 10
{"id":"3485-KV-59"}
{"id":"6846-OT-19"}
{"id":"5706-GF-02"}
{"id":"5760-XR-28"}
{"id":"6254-EY-45"}
{"id":"5200-LL-28"}
{"id":"7407-ZN-94"}
{"id":"5547-PY-31"}
{"id":"9949-TY-61"}
{"id":"0383-IQ-93"}