Aller au contenu

Avec ou sans points⚓︎

Une adresse électronique est composée de deux parties séparées par un « @ » :

  • la partie locale, avant le « @ »,
  • la partie domaine, après le « @ ».

Certains services de messagerie ignorent les caractères . dans la partie locale. Ainsi, sur ces services, les messages envoyés aux adresses cours.premiere@e-nsi.fr, co.ur.spremi.ere@e-nsi.fr et cours..premiere@e-nsi.fr arrivent tous au même destinataire courspremiere@e-nsi.fr.

Par contre, les adresses cours_premiere@e-nsi.fr, courspremier@e-nsi.fr et courspremiere@aeif.org ne correspondent pas à ce destinataire.

On cherche dans cet exercice à vérifier qu'une adresse correspond bien à une adresse de référence. L'adresse de référence est l'adresse électronique écrite sans aucun point dans la partie locale.

Les adresses se correspondent donc si :

  • sans tenir compte des caractères ., les deux parties locales comportent les mêmes caractères présents dans le même ordre,
  • si les parties domaines sont strictement égales.

On garantit que les deux adresses ne comptent qu'un seul caractère '@'.

Écrire la fonction correspond qui détermine si adresse correspond à reference. Les deux arguments sont :

  • adresse : l'adresse électronique dont on souhaite tester la correspondance,

  • reference : l'adresse électronique de référence.

La fonction correspond renvoie True ou False selon que les deux adresses correspondent ou non.

Contrainte

On interdit d'utiliser les méthodes split et replace des chaînes de caractères .

Exemples

🐍 Console Python
>>> correspond("courspremiere@e-nsi.fr", "courspremiere@e-nsi.fr")
True
>>> correspond("cours.premiere@e-nsi.fr", "courspremiere@e-nsi.fr")
True
>>> correspond("co.ur.spremi.ere@e-nsi.fr", "courspremiere@e-nsi.fr")
True
>>> correspond("cours..premiere@e-nsi.fr", "courspremiere@e-nsi.fr")
True
>>> correspond(".courspremiere.@e-nsi.fr", "courspremiere@e-nsi.fr")
True
>>> correspond("cours_premiere@e-nsi.fr", "courspremiere@e-nsi.fr")
False
>>> correspond("courspremier@e-nsi.fr", "courspremiere@e-nsi.fr")
False
>>> correspond("courspremiere@aeif.org", "courspremiere@e-nsi.fr")
False
###
# Testsbksl-nlassert correspond("courspremiere@e-nsi.fr", "courspremiere@e-nsi.fr") == Truebksl-nlassert correspond("cours.premiere@e-nsi.fr", "courspremiere@e-nsi.fr") == Truebksl-nlassert correspond("co.ur.spremi.ere@e-nsi.fr", "courspremiere@e-nsi.fr") == Truebksl-nlassert correspond("cours..premiere@e-nsi.fr", "courspremiere@e-nsi.fr") == Truebksl-nlassert correspond(".courspremiere.@e-nsi.fr", "courspremiere@e-nsi.fr") == Truebksl-nlassert correspond("courspy-undpremiere@e-nsi.fr", "courspremiere@e-nsi.fr") == Falsebksl-nlassert correspond("courspremier@e-nsi.fr", "courspremiere@e-nsi.fr") == Falsebksl-nlassert correspond("courspremiere@aeif.org", "courspremiere@e-nsi.fr") == Falsebksl-nlbksl-nlbksl-nlbksl-nl# Tests supplémentairesbksl-nlassert not correspond("spepy-undisn@serveur.org", "spepy-undnsi@serveur.org")bksl-nlassert not correspond("specialitepy-undnsi@serveur.org", "spepy-undnsi@serveur.org")bksl-nlassert correspond("..spepy-undnsi@serveur.org", "spepy-undnsi@serveur.org")bksl-nlassert correspond("spepy-undnsi..@serveur.org", "spepy-undnsi@serveur.org")bksl-nlbksl-nlbksl-nlimport string, randombksl-nlbksl-nlcarcateres = string.asciipy-undlowercase + string.digits[:-2] + "-py-und"bksl-nlserveurpy-undA = "@e-nsi.fr"bksl-nlserveurpy-undB = "@e-nsi.de"bksl-nlserveurpy-undC = "@e-nsi.fra"bksl-nlfor py-und in range(100):bksl-nl localepy-undref = [random.choice(carcateres) for py-und in range(10)]bksl-nl reference = "".join(localepy-undref) + serveurpy-undAbksl-nl localepy-undadr = localepy-undref.copy()bksl-nl for nbpy-undpoints in range(random.randrange(0, 5)):bksl-nl position = random.randrange(0, len(localepy-undadr))bksl-nl localepy-undadr.insert(position, ".")bksl-nlbksl-nl # Identiquesbksl-nl adresse = "".join(localepy-undadr) + serveurpy-undAbksl-nl assert correspond(adresse, reference), f"Erreur avec {adresse} et {reference}"bksl-nl bksl-nl # Serveurs différentsbksl-nl adresse = "".join(localepy-undadr) + serveurpy-undBbksl-nl assert not correspond(adresse, reference), f"Erreur avec {adresse} et {reference}"bksl-nl bksl-nl # Serveurs différents (plus long)bksl-nl adresse = "".join(localepy-undadr) + serveurpy-undCbksl-nl assert not correspond(adresse, reference), f"Erreur avec {adresse} et {reference}"bksl-nl bksl-nl # Partie locale différentebksl-nl adresse = "".join(localepy-undref)[:-2] + "89" + serveurpy-undAbksl-nl assert not correspond(adresse, reference), f"Erreur avec {adresse} et {reference}"bksl-nl bksl-nl # Partie locale plus courtebksl-nl adresse = "".join(localepy-undref)[:-2] + serveurpy-undAbksl-nl assert not correspond(adresse, reference), f"Erreur avec {adresse} et {reference}"bksl-nl bksl-nl # Partie locale plus longuebksl-nl adresse = "".join(localepy-undref) + "".join(localepy-undref)[:2] + serveurpy-undAbksl-nl assert not correspond(adresse, reference), f"Erreur avec {adresse} et {reference}"bksl-nlbksl-nl 5/5

def correspond(adresse, reference):bksl-nl ...bksl-nlbksl-nlbksl-nl# Testsbksl-nlassert correspond("courspremiere@e-nsi.fr", "courspremiere@e-nsi.fr") == Truebksl-nlassert correspond("cours.premiere@e-nsi.fr", "courspremiere@e-nsi.fr") == Truebksl-nlassert correspond("co.ur.spremi.ere@e-nsi.fr", "courspremiere@e-nsi.fr") == Truebksl-nlassert correspond("cours..premiere@e-nsi.fr", "courspremiere@e-nsi.fr") == Truebksl-nlassert correspond(".courspremiere.@e-nsi.fr", "courspremiere@e-nsi.fr") == Truebksl-nlassert correspond("courspy-undpremiere@e-nsi.fr", "courspremiere@e-nsi.fr") == Falsebksl-nlassert correspond("courspremier@e-nsi.fr", "courspremiere@e-nsi.fr") == Falsebksl-nlassert correspond("courspremiere@aeif.org", "courspremiere@e-nsi.fr") == Falsebksl-nlbksl-nldef correspond(adresse, reference):bksl-nl longueurpy-undadr = len(adresse)bksl-nl longueurpy-undref = len(reference)bksl-nl bksl-nl ipy-undadr = 0bksl-nl ipy-undref = 0bksl-nl bksl-nl local = Truebksl-nl bksl-nl while (ipy-undadr < longueurpy-undadr) and (ipy-undref < longueurpy-undref):bksl-nl if adresse[ipy-undadr] == "." and local:bksl-nl ipy-undadr += 1bksl-nl elif adresse[ipy-undadr] != reference[ipy-undref]:bksl-nl return Falsebksl-nl else:bksl-nl if reference[ipy-undref] == "@":bksl-nl local = Falsebksl-nl ipy-undadr += 1bksl-nl ipy-undref += 1bksl-nl return (ipy-undadr == longueurpy-undadr) and (ipy-undref == longueurpy-undref)bksl-nlbksl-nlbksl-nl# Testsbksl-nlassert correspond("courspremiere@e-nsi.fr", "courspremiere@e-nsi.fr") == Truebksl-nlassert correspond("cours.premiere@e-nsi.fr", "courspremiere@e-nsi.fr") == Truebksl-nlassert correspond("co.ur.spremi.ere@e-nsi.fr", "courspremiere@e-nsi.fr") == Truebksl-nlassert correspond("cours..premiere@e-nsi.fr", "courspremiere@e-nsi.fr") == Truebksl-nlassert correspond(".courspremiere.@e-nsi.fr", "courspremiere@e-nsi.fr") == Truebksl-nlassert correspond("courspy-undpremiere@e-nsi.fr", "courspremiere@e-nsi.fr") == Falsebksl-nlassert correspond("courspremier@e-nsi.fr", "courspremiere@e-nsi.fr") == Falsebksl-nlassert correspond("courspremiere@aeif.org", "courspremiere@e-nsi.fr") == Falsebksl-nlbksl-nl

A

Une première approche consiste à simplifier l'adresse à tester en supprimant les .. On recopie ainsi les caractères valides jusqu'à rencontrer le @. Après celui-ci, on recopie la fin de l'adresse sans modification.

Cette étape de simplification effectuée on peut renvoyer le résultat de la comparaison entre l'adresse « simplifiée » et l'adresse de référence.

Le code ci-dessous procède ainsi :

🐍 Script Python
def correspond(adresse, reference):
    adresse_simplifiee = ""
    i = 0
    while adresse[i] != "@":
        if adresse[i] != ".":
            adresse_simplifiee = adresse_simplifiee + adresse[i]
        i = i + 1
    for j in range(i, len(adresse)):
        adresse_simplifiee = adresse_simplifiee + adresse[j]
    return adresse_simplifiee == reference

Parfaitement fonctionnelle, cette méthode présente toutefois un petit désavantage : l'adresse à tester est lue deux fois. Une fois lors de la simplification et une seconde lors de la comparaison.

La méthode présentée ci-dessous permet de comparer les adresses en une seule « passe ».

Le traitement des adresses diffère selon que l'on est dans la partie locale ou domaine. Le booléen local vaut True dans le premier cas, False sinon.

Dans la partie locale on ignore les "." en passant au caractère suivant dans l'adresse à tester.

Si le caractère lu dans l'adresse à tester n'est pas un point et diffère du caractère correspondant dans l'adresse de référence on renvoie False, quelle que soit la partie étudiée.

Dans le dernier cas de figure, les caractères sont identiques. S'il s'agit du "@", on bascule la valeur de local à False. On peut alors passer aux caractères suivants dans chaque adresse.

À la fin de la fonction on vérifie que l'on est arrivé à la fin de chaque adresse.

Notons qu'il est possible de résoudre cet exercice en utilisant une expression régulière :

🐍 Script Python
import re

def correspond(adresse, reference):
    adresse = "".join(re.findall(r"@.+|[^.]+(?=@)|[^.]+", adresse))
    return adresse == reference

Cette expression régulière ne permet toutefois pas de tester la conformité d'une adresse électronique. Voir cette page pour une proposition d'expression régulière validant les adresses électroniques.

Z