AccueilGuides TechniquesHTML Entity Encoder & Decoder
ENESJADEPTFR
Architecture & Guide Pratique

Encodeur et décodeur d'entités HTML : Architecture technique et guide approfondi

Le langage HTML structure le Web selon le [WHATWG HTML Living Standard](https://html.spec.whatwg.org/) et le W3C, réservant des délimiteurs stricts — esperluette (&), chevrons (<, >) et guillemets (",

13 min de lecture
2539 mots
Zéro Transmission Serveur
Outil Interactif Disponible

Exécutez cet utilitaire dans votre navigateur avec 100 % de confidentialité locale.

Ouvrir l'Outil Interactif

# Encodeur et décodeur d'entités HTML : Architecture technique et guide approfondi

Le langage HTML structure le Web selon le WHATWG HTML Living Standard et le W3C, réservant des délimiteurs stricts — esperluette (&), chevrons (<, >) et guillemets (", ') — pour dissocier balises et texte brut.

Tout texte non assaini contenant ces délimiteurs induit erreurs de rendu, troncatures et failles XSS (Cross-Site Scripting). Pour restituer des caractères littéraux sans altérer le DOM, les applications recourent aux entités HTML (Character References).

La suite ToolsAA Encodeur & Décodeur d'entités HTML réunit un encodeur d'entités HTML en ligne, un convertisseur bidirectionnel et un banc d'essai pour échapper les caractères HTML spéciaux et décoder les entités HTML. Conçue à 100 % côté client ("use client"), la tokenisation s'opère en mémoire locale : zéro transmission réseau et conformité RGPD.


# Présentation générale et cas d'usage en production

Les entités HTML substituent des caractères réservés ou non-ASCII par des séquences conformes à SGML et XML. Une entité débute par & et s'achève par ;. Elle encapsule un mnémonique (référence nommée) ou un point de code Unicode (référence numérique, ou NCR).

text 9 lines
+---------------------------------------------------------------------------------------------------+
|                                 Anatomie des entités de caractères HTML                           |
|  Nommée :       &        amp          ;    --> Se résout en : '&' (U+0026)                        |
|                [Préfixe] [Mnémonique] [Délimiteur]                                                |
|  Décimale :     &#       38           ;    --> Se résout en : '&' (Point de code Unicode Base-10) |
|                [Préfixe] [Point Décimal]                                                          |
|  Hexadécimale : &#x      26           ;    --> Se résout en : '&' (Point de code Unicode Base-16) |
|                [Préfixe] [Point Hexa]                                                             |
+---------------------------------------------------------------------------------------------------+

# Cas d'usage clés en ingénierie logicielle

  • Atténuation des failles XSS : Remplacer < par &lt; et > par &gt; isole la saisie en texte passif (PCDATA), neutralisant l'exécution de scripts.
  • Documentation et tutoriels : Affiche du HTML ou JSX littéral dans <code>, convertissant <div class="hero"> en &lt;div class=&quot;hero&quot;&gt;.
  • Attributs de formulaires : Prévient la sortie de champ dans <input value="..."> en échappant les guillemets (" en &quot;, ' en &#39;).
  • Fidélité typographique : Préserve &nbsp;, &laquo;/&raquo;, &mdash; et &copy; pour un rendu multiplateforme uniforme.
  • Flux XML et SVG : Valide les grammaires XML 1.0 où toute esperluette brute interrompt l'analyse.

# Traitement côté client et confidentialité absolue

Transmettre des données à des serveurs distants crée un risque d'exfiltration : code propriétaire, schémas SQL ou jetons. Cela viole le RGPD et SOC 2. ToolsAA applique une architecture sans serveur (Zero-Server) : tout s'exécute en mémoire locale sans requêtes sortantes.


# Architecture technique et fonctionnement interne

La gestion des entités concilie les standards SGML, la rigueur XML, le standard vivant WHATWG et l'environnement JavaScript.

# 1. Le continuum des spécifications : XML 1.0, HTML 4.01 et WHATWG

  • XML 1.0 (W3C) : N'autorise que cinq entités prédéfinies (&amp;, &lt;, &gt;, &quot;, &apos;). Les autres entités nommées requièrent une DTD ; les NCR restent valides.
  • HTML 4.01 (W3C) : Normalisait 252 entités mais omettait &apos;.
  • WHATWG HTML Living Standard : Catalogue 2 231 entités et formalise la récupération sans point-virgule.

# 2. Mécanique binaire d'Unicode et paires de substitution UTF-16

En JavaScript, les chaînes reposent sur des unités UTF-16 (16 bits). Les caractères du plan BMP (U+0000 à U+FFFF) occupent une unité, tandis que les plans astraux (🚀, U+1F680) requièrent une paire de substitution : demi-codet haut (0xD800–0xDBFF) et demi-codet bas (0xDC00–0xDFFF). Les encodeurs naïfs tronquent ces glyphes en entités corrompues (&#55357;&#56960;). ToolsAA dérive la valeur scalaire globale via codePointAt() :

$$ ext{CodePoint} = (( ext{High} - 0 ext{xD800}) imes 0 ext{x400}) + ( ext{Low} - 0 ext{xDC00}) + 0 ext{x10000}$$

La référence numérique unifiée générée est alors valide : &#128640; (décimale) ou &#x1F680; (hexadécimale).

# 3. Typologie des formats : Nommées vs Décimales vs Hexadécimales

  • Références nommées (&nom;) : Mnémoniques textuels (&amp;, &euro;) résolus par les tables dictionnaires du navigateur.
  • NCR décimales (&#[0-9]+;) : Points de code Unicode en base 10 (&#38;, &#8364;), analysés universellement sans schéma DTD.
  • NCR hexadécimales (&#x[0-9a-fA-F]+;) : Points de code Unicode en base 16 (&#x26;, &#x20AC;), recommandés dans les flux XML.

# 4. DOMParser et isolation des jetons : Pourquoi innerHTML est un anti-pattern

Décoder via innerHTML d'un conteneur temporaire introduit trois risques critiques :

  • XSS basé sur le DOM : Les balises injectées (<img src=x onerror=alert(1)>) exécutent immédiatement leur script lors de l'assignation.
  • Suppression de balises (Tag Stripping) : Tout mélange de balises et d'entités détruit le balisage extérieur lors de l'extraction par textContent.
  • Requêtes réseau fantômes : Les médias injectés émettent des requêtes HTTP vers des serveurs tiers.

ToolsAA utilise une isolation par expression régulière (/&(#(?:[xX][0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+);/g) avec dictionnaire immuable, sans interaction avec le DOM.

# 5. API Web, concurrence React et ingénierie de la performance

  • Concurrence React 18+ : La saisie est isolée via useDeferredValue(), préservant 60 FPS.
  • Mémoire tampon : Les segments transformés s'assemblent en une passe (chunks.join("")) en $O(N)$ linéaire.
  • Canvas hors écran : Les métriques sont tracées hors écran pour éliminer les reflows.
  • Web Crypto & WASM : Les gros volumes (> 1 Mo) bénéficient d'un contrôle SHA-256 via Web Crypto et d'un parseur WebAssembly.

# Guide pratique étape par étape

# Étape 1 : Ingestion des données et préréglages

Collez votre texte brut ou choisissez un profil : Défense XSS, Nettoyage XML/SVG ou Typographie internationale. Les fichiers se chargent directement via l'API locale FileReader.

# Étape 2 : Sélection du périmètre et du format

  • Essentiel (Compatible XML) : Encode les cinq délimiteurs fondamentaux (&, <, >, ", ').
  • Caractères non-ASCII : Convertit tous les points de code supérieurs à 127 (U+007F).
  • Tous les caractères (Obfuscation) : Convertit l'ensemble du texte en références numériques.
  • Basculez entre Entités nommées (&amp;), NCR décimales (&#38;) et NCR hexadécimales (&#x26;).

# Étape 3 : Options granulaires d'échappement

  • Paramétrez l'échappement des guillemets (' s'encode par défaut en &#39;).
  • Convertissez les espaces insécables ( ) en &nbsp;.
  • Convertissez les sauts de ligne en balises <br /> pour les e-mails et formulaires.

# Étape 4 : Décodage bidirectionnel sécurisé

  • Extraction unifiée : Décode simultanément entités nommées, décimales et hexadécimales.
  • Résolution héritée : Résout les entités historiques non fermées (&copy 2026).
  • Normalisation des sauts : Restitue les balises <br /> en retours chariot standard (`

`).

# Étape 5 : Analyse des métriques et export

Consultez le décompte de caractères, la taille en octets UTF-8 et l'inflation mémoire. Copiez le résultat ou téléchargez-le en fichier texte.


# Implémentations de code prêtes pour la production

# 1. Implémentation en TypeScript / JavaScript moderne

Un module autonome gérant les paires de substitution 32 bits et le décodage sécurisé par expression régulière :

typescript 43 lines
export type EntityFormat = "named" | "decimal" | "hex";

export class HtmlEntityCodec {
  private static readonly NAMED: Record<string, string> = {
    "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;",
    " ": "&nbsp;", "©": "&copy;", "®": "&reg;", "™": "&trade;", "€": "&euro;",
  };

  public static encode(str: string, format: EntityFormat = "named", nonAscii = false): string {
    const out: string[] = [];
    for (let i = 0; i < str.length; ) {
      const cp = str.codePointAt(i)!;
      const ch = String.fromCodePoint(cp);
      if (this.NAMED[ch]) {
        out.push(format === "named" ? this.NAMED[ch] : format === "decimal" ? `&#${cp};` : `&#x${cp.toString(16).toUpperCase()};`);
      } else if (nonAscii && cp > 127) {
        out.push(format === "hex" ? `&#x${cp.toString(16).toUpperCase()};` : `&#${cp};`);
      } else {
        out.push(ch);
      }
      i += cp > 0xffff ? 2 : 1;
    }
    return out.join("");
  }

  public static decode(str: string): string {
    const map: Record<string, string> = {
      "&amp;": "&", "&lt;": "<", "&gt;": ">", "&quot;": '"', "&apos;": "'", "&#39;": "'",
      "&nbsp;": " ", "&copy;": "©", "&euro;": "€"
    };
    return str.replace(/&(#(?:[xX][0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+);/g, (m, ent) => {
      if (ent.startsWith("#x") || ent.startsWith("#X")) {
        const cp = parseInt(ent.slice(2), 16);
        return cp <= 0x10ffff && !(cp >= 0xd800 && cp <= 0xdfff) ? String.fromCodePoint(cp) : m;
      }
      if (ent.startsWith("#")) {
        const cp = parseInt(ent.slice(1), 10);
        return cp <= 0x10ffff && !(cp >= 0xd800 && cp <= 0xdfff) ? String.fromCodePoint(cp) : m;
      }
      return map[m] || m;
    });
  }
}

# 2. Implémentation en Python 3.11+ moderne

Un module typé pour la conversion en entités numériques, la validation des demi-codets et l'assainissement HTML :

python 38 lines
from typing import Literal
import html, re

class HtmlEntityCodec:
    _RE = re.compile(r"&(#(?:[xX][0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+);")
    _CORE = {"&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;"}

    @classmethod
    def encode(cls, text: str, mode: Literal["named", "decimal", "hex"] = "named", non_ascii: bool = False) -> str:
        out = []
        for ch in text:
            cp = ord(ch)
            if ch in cls._CORE:
                out.append(cls._CORE[ch] if mode == "named" else f"&#{cp};" if mode == "decimal" else f"&#x{cp:X};")
            elif non_ascii and cp > 127:
                out.append(f"&#x{cp:X};" if mode == "hex" else f"&#{cp};")
            else:
                out.append(ch)
        return "".join(out)

    @classmethod
    def decode(cls, text: str) -> str:
        def _rep(m: re.Match) -> str:
            raw, ent = m.group(0), m.group(1)
            if ent.startswith(("#x", "#X")):
                try:
                    cp = int(ent[2:], 16)
                    return chr(cp) if 0 <= cp <= 0x10FFFF and not (0xD800 <= cp <= 0xDFFF) else raw
                except ValueError:
                    return raw
            if ent.startswith("#"):
                try:
                    cp = int(ent[1:], 10)
                    return chr(cp) if 0 <= cp <= 0x10FFFF and not (0xD800 <= cp <= 0xDFFF) else raw
                except ValueError:
                    return raw
            return html.unescape(raw)
        return cls._RE.sub(_rep, text)

# Pièges courants, cas limites et guide de dépannage

# 1. Le double encodage (&amp;amp; et &amp;lt;)

Convertit & en &amp;, transformant &lt; en &amp;lt; et provoquant un affichage littéral indésirable.

  • Solution : Encodez uniquement à la frontière de présentation finale. Vérifiez l'idempotence (decode(str) !== str).

# 2. Échappement dépendant du contexte

L'encodage protège texte et attributs, mais échoue dans les balises <script> ou dans les paramètres d'URL.

  • Solution : Utilisez JSON.stringify() en remplaçant < par \u003C dans les scripts, et encodeURIComponent pour les URLs.

# 3. L'incompatibilité de l'entité &apos; en HTML 4

Omise d'HTML 4.01, l'entité &apos; provoque des erreurs de rendu dans les clients de messagerie anciens.

  • Solution : Privilégiez la référence décimale &#39;, universellement reconnue en HTML, XML et SVG.

# 4. Entités sans point-virgule en mode Quirks

WHATWG tolère les entités non fermées (&copy 2026), mais les parseurs XML stricts rejettent ces fragments.

  • Solution : Terminez systématiquement chaque référence d'entité par un point-virgule (;).

# 5. Troncature des paires UTF-16 (Émojis corrompus)

Découper une chaîne par charAt() scinde les glyphes 32 bits (🚀) en demi-codets orphelins (&#55357;&#56960;).

  • Solution : Itérez avec codePointAt() et avancez le curseur de deux unités pour les caractères hors BMP.

# 6. Décodage destructeur et failles XSS via innerHTML

Décoder par innerHTML supprime les balises valides et exécute les scripts injectés (<img src=x onerror=alert(1)>).

  • Solution : Décodez par substitution d'expressions régulières sans instanciation dans l'arbre DOM.

# Foire aux questions technique (FAQ)

# Q1 : Quelle est la différence entre entité nommée, NCR décimale et NCR hexadécimale ?

Réponse : Une entité nommée emploie un mnémonique (&copy;), la NCR décimale la base 10 (&#169;), et l'hexadécimale la base 16 (&#xA9;). Rendu identique, mais les NCR fonctionnent en XML sans DTD.

# Q2 : Pourquoi l'encodage d'entités ne suffit-il pas contre les failles XSS dans <script> ?

Réponse : Le moteur analyse <script> selon la syntaxe JavaScript sans décoder les entités HTML. Les scripts exigent un échappement JS (JSON.stringify() remplaçant < par \u003C).

# Q3 : Pourquoi &apos; pose-t-il problème dans les e-mails anciens et pourquoi préférer &#39; ?

Réponse : Absent d'HTML 4.01, &apos; est ignoré par les moteurs d'e-mails historiques. La référence numérique &#39; assure une compatibilité universelle sur tous les parseurs HTML et XML.

# Q4 : Comment les émojis sont-ils traités en entités HTML ?

Réponse : Les émojis (🔥) forment des paires UTF-16. Un encodeur calcule la valeur scalaire 32 bits (128293) pour générer une entité unifiée (&#128293; ou &#x1F525;).

# Q5 : Pourquoi innerHTML est-il dangereux pour décoder du texte ?

Réponse : L'assignation à innerHTML exécute immédiatement les charges injectées (<img src=x onerror=alert(1)>) et détruit le balisage valide lors de la lecture par textContent.

# Q6 : Comment détecter si une chaîne est déjà encodée en entités HTML ?

Réponse : Testez le motif /&(#(?:[xX][0-9a-fA-F]+|[0-9]+)|[a-zA-Z0-9]+);/. Si decode(str) !== str, la chaîne comporte déjà des entités actives.

# Q7 : Mes données sensibles sont-elles transmises à un serveur avec ToolsAA ?

Réponse : Non. ToolsAA fonctionne exclusivement côté client ("use client"). Tokenisation et calculs s'exécutent en mémoire dans le navigateur : zéro transfert réseau.

# Q8 : Combien d'entités nommées le standard WHATWG supporte-t-il ?

Réponse : XML 1.0 définit 5 entités et HTML 4.01 en comptait 252. Le standard vivant WHATWG catalogue 2 231 références nommées (maths, grec, typographie).


# Tableau comparatif technique : Formats et contextes d'entités HTML

Format / TypeEntité nomméeNCR DécimaleNCR HexaUTF-8 Brut
StandardWHATWG / SGMLW3C / ISO 10646W3C / RFC 5198Consortium Unicode
Couverture2 231 symboles1 114 112 points1 114 112 points1 114 112 points
Sécurité XML 1.05 entités seulementCompatibleCompatibleCompatible
HTML 4.01 Legacy252 glyphes (Sans &apos;)CompatibleCompatibleSelon encodage page
Poids en octetsModéré (4 à 10 o)Compact (4 à 9 o)Compact (5 à 9 o)Minimal (1 à 4 o)
LisibilitéÉlevée (&copy;)Faible (&#169;)Faible (&#xA9;)Optimale (Glyphe)
Attributs HTMLOui (Si échappée)OuiOuiNécessite échappement
Balise <script>Non (Erreur JS)Non (Erreur JS)Non (Erreur JS)Requiert échappement JS

# Conclusion

Séparer balisage et données textuelles est fondamental en ingénierie Web. Qu'il s'agisse de neutraliser les attaques XSS, d'afficher du code dans une documentation ou d'échanger des flux XML stricts, l'encodage des entités garantit un rendu déterministe sans rupture syntaxique.

En adoptant les bonnes pratiques — privilégier &#39; sur &apos;, assembler les paires UTF-16 de 32 bits pour les émojis et isoler les jetons par expressions régulières plutôt que via innerHTML —, les ingénieurs éliminent les doubles encodages. La suite ToolsAA Encodeur & Décodeur d'entités HTML garantit une exécution déterministe, 100 % côté client dans le navigateur, avec une confidentialité absolue.

Besoin d'utiliser cet outil maintenant ?

Aucune installation requise. Traitement 100 % privé dans le navigateur avec résultat instantané.