import random
import hashlib

def valider_mdp(mot_de_passe: str) -> bool:
    # booléens indiquant le respect de chacun des 5 contraintes
    est_long = True
    a_majuscule = False
    a_minuscule = False
    a_chiffre = False
    a_special = False
    # ensemble des caractères spéciaux acceptés :
    caracteres_speciaux = "!@#$%^&*()_+-=[]{}|;:,.<>?/"
    if len(mot_de_passe) < 12:
        est_long = False
    for carac in mot_de_passe:
        if carac.isupper():
            a_majuscule = True
        elif carac.islower():
            a_minuscule = True
        elif carac.isdigit():
            a_chiffre = True
        elif carac in caracteres_speciaux:
            a_special = True
    return est_long and a_majuscule and a_minuscule and a_chiffre and a_special

def tests_valider_mdp():
    assert valider_mdp("1_tropCourt") == False, "erreur sur un mot de passe trop court"
    assert valider_mdp("Un_sans_chiffre") == False, "erreur sur un mot de passe sans chiffre"
    assert valider_mdp("1_sans_chiffre") == False, "erreur sur un mot de passe sans majuscule"
    assert valider_mdp("1_SANS_MINUSCULE") == False, "erreur sur un mot de passe sans minuscule"
    assert valider_mdp("1SansCaractereSpecial") == False, "erreur sur un mot de passe sans caractère spécial"
    assert valider_mdp("Enf1!T@nt_DAttempte...") == True, "erreur sur un mot de passe convenable"
    print("tests sur valider_mdp réussis !")  

caracteres = "azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN0123456789"
lst = [carac for carac in caracteres] # liste des caractères de la chaîne caracteres
def creer_sel(long: int) -> str:
	ch = ""
	for _ in range(long):
		carac = random.choice(lst)
		ch = ch + carac
	return ch

def rajout_sel(dico: dict, nom: str) -> dict:
    if nom not in dico:
        sel = creer_sel(10)
        dico[nom] = sel
    return dico

def saler_hasher_mdp(mot_de_passe: str, sel: str) -> str:
    return hashlib.sha256((mot_de_passe + sel).encode()).hexdigest() 

def hacher(nom_utilisateur: str, dico_sel: dict, mot_de_passe: str):
    """On suppose ici que nom_utilisateur est une cle du dictionnaire dico_sel mais vérifier dans une assertion"""
    assert nom_utilisateur in dico_sel
    if valider_mdp(mot_de_passe):
        sel = dico_sel[nom_utilisateur]
        return saler_hasher_mdp(mot_de_passe, sel)

dico_sel = {"utilisateur1" : "AXi8g22CAN", "utilisateurB@c": "3VD7SFitP9", "admin123!": "J9ysNu9Pjt", "azerty007": "IDB40mFq7c"} # Rajout à la partie C

if __name__ == "__main__":
    # exécution lorsque l'on lance ce programme directement
    # mais pas lors d'une importation
    tests_valider_mdp()    
    print(f"exemmle de sel de longueur 10 {creer_sel(10)}")
    print(hacher("utilisateur1", dico_sel, "1mot2passe_PAS_sur?"))