4 points par GN⁺ 2024-04-24 | 3 commentaires | Partager sur WhatsApp
  • Lorsqu’une personne doit lire et transmettre un identifiant — signalement de bug, saisie d’un code de réduction, suivi de livraison, etc. — les ambiguïtés visuelles comme O/0 ou I/l/1/7 conduisent facilement à des erreurs de saisie
  • La confusion augmente selon la police et l’écriture manuscrite, et des combinaisons où la distinction devient floue reviennent régulièrement, comme 5/S, 2/Z, 8/B, 6/G, 9/q/g
  • Pour les identifiants manipulés directement par des personnes, comme ceux du support client, les ID d’erreur ou les ID produit, choisir un jeu de caractères lisible compte davantage pour la qualité en usage réel qu’un jeu de caractères arbitrairement vaste
  • En distinguant les majuscules et les minuscules, un ID de 5 caractères peut produire 418,195,493 combinaisons, mais sans distinction de casse ce nombre tombe à 5,153,632, ce qui impose un compromis entre longueur et sécurité
  • Les ID sensibles à la casse permettent de rester courts, mais certains systèmes tiers ou protocoles peuvent fonctionner de façon insensible à la casse, ce qui peut créer des problèmes lors de l’intégration

Confusion de caractères dans les ID lus par des humains

  • Lorsqu’un ID est écrit ou transmis dans des interactions avec un système, comme un rapport de bug, la saisie d’un code de réduction ou le suivi d’une livraison, des confusions de caractères évitables peuvent dégrader l’expérience utilisateur
  • Les combinaisons typiques de caractères visuellement ambigus sont les suivantes
    • O / 0 : si le zéro n’a ni barre oblique ni point, la lettre O et le chiffre 0 peuvent se ressembler
    • I / l / 1 / 7 : le I majuscule, le l minuscule, le chiffre 1 et le chiffre 7 sont difficiles à distinguer dans de nombreux imprimés et écritures manuscrites
    • 5 / S, 2 / Z, 8 / B, 6 / G, 9 / q / g : ils peuvent être confondus avec certaines polices, des polices stylisées ou en écriture manuscrite
  • La chaîne d’exemple 9qg6G8B2Z5SIl170O sert de point de comparaison dans plusieurs polices système comme Arial, Helvetica, Courier, Times, Verdana, Georgia, Tahoma, Impact ou Comic Sans
  • Certaines combinaisons, comme I et l, peuvent rester ambiguës dans plusieurs polices, et d’autres, comme 9qg, deviennent encore plus déroutantes lorsqu’elles sont écrites à la main
    • Types d’ID particulièrement problématiques

    • Codes de réduction échangés avec le support client
    • Codes de suivi utilisés pour la livraison ou la logistique
    • ID d’erreur nécessaires à la reproduction de problèmes et au traitement des demandes
    • ID produit utilisés pour l’identification des produits

Compromis entre sensibilité à la casse et jeu de caractères

  • La question de savoir si un ID considère abc et ABC comme la même valeur doit être tranchée en même temps que les règles de génération
  • En distinguant majuscules et minuscules tout en excluant les caractères visuellement ambigus, il reste 53 caractères possibles
  • Sans distinction de casse, le nombre de caractères possibles tombe à 22
  • Le nombre de combinaisons possibles selon la longueur de l’ID est le suivant
    • 5 caractères, sensible à la casse : 53^5 = 418,195,493
    • 5 caractères, insensible à la casse : 22^5 = 5,153,632
    • 8 caractères, sensible à la casse : 53^8 = 62,259,690,411,361
    • 8 caractères, insensible à la casse : 22^8 = 54,875,873,536
  • Au final, le choix consiste à trouver un équilibre entre des ID courts mais plus susceptibles d’être confondus et des ID plus longs mais plus faciles à lire
  • Utiliser à la fois des majuscules et des minuscules peut finir par provoquer un comportement inattendu dans un système tiers ou un protocole insensible à la casse
    • Un système commercial permettait aux utilisateurs de choisir iD et id comme deux ID différents, mais lors de la recherche d’un ID inexistant, il effectuait une correspondance insensible à la casse et renvoyait de mauvaises données
    • La réponse donnée à ce bug a été qu’il s’agissait d’un comportement conçu pour la « commodité »

Il peut aussi être nécessaire d’éviter des combinaisons, pas seulement des caractères isolés

  • Certaines combinaisons de caractères peuvent elles-mêmes ressembler à d’autres caractères
    • rn peut ressembler à m
    • vv peut ressembler à w
  • Exclure massivement des caractères pour cette seule raison risquerait de trop réduire le jeu de caractères disponible ; il peut donc être plus réaliste d’éviter seulement certaines combinaisons lors de la génération
  • Dans les situations où l’identifiant est transmis à l’oral, la similarité phonétique peut aussi être prise en compte
    • Par exemple, b et p peuvent se ressembler à l’oreille lorsqu’ils sont prononcés

Méthodes existantes à consulter

  • Le Base32 de Crockford décode les caractères ambigus vers la même valeur et tient aussi compte du risque d’expressions obscènes accidentelles
  • Open Location Code utilise le jeu de caractères 23456789CFGHJMPQRVWX
    • Ce jeu de caractères a été choisi pour éviter les caractères visuellement ambigus ainsi que l’orthographe de mots de langues courantes
    • Il inclut toutefois à la fois 6 et G, ainsi que 9 et Q

3 commentaires

 
roxie 2025-01-29
 
roxie 2025-01-29

Le fait qu’ils aient même pris en compte la prononciation est vraiment remarquable.

 
GN⁺ 2024-04-24
Avis de Hacker News
  • Au travail, nous avions expédié des millions d’appareils avec des numéros de série, sans exclure le moindre caractère ou chiffre ambigu, et les clients avaient énormément de mal à les lire correctement.
    J’ai dû écrire un script à base d’expressions régulières qui générait toutes les combinaisons possibles de fautes de lecture à partir de la valeur donnée par le client, puis n’affichait que celles qui correspondaient à la base de données de l’usine ; ensuite, on recoupait avec d’autres informations, comme la date, pour déduire le vrai numéro de série.
    Le plus ironique, c’est que certains chiffres ne changeaient jamais et que, pour certaines positions, seuls 0, 1 et 2 étaient nécessaires pour identifier l’usine ; on n’avait donc pas besoin de tout le jeu de caractères au départ. Comme si l’on avait cru qu’on allait en fabriquer 8 billiards.

    • Il est souvent utile, ou du moins considéré comme utile, d’éviter que les numéros de série révèlent des informations commerciales.
      Par exemple, si l’on numérote des produits séquentiellement, comme 1, 2, 3, il devient assez facile d’estimer les ventes totales à partir d’un petit échantillon. Rendre les numéros de série valides difficiles à deviner peut aussi aider à éviter des abus comme la fraude aux remboursements.
      Bien sûr, même avec ces préoccupations, on peut aussi éviter les caractères difficiles à lire ; et si cela signifie que quelqu’un réfléchit au système de numérotation à utiliser, il aurait justement dû être plus conscient de ce problème. En réalité, il semble plus probable que quelqu’un y ait réfléchi environ 30 secondes avant de dire : « avec autant de positions, on n’en manquera jamais, terminé ».
    • Maintenant que j’y pense, c’est peut-être aussi la raison, ou au moins l’un des facteurs, pour lesquels les numéros de série Apple n’ont pas de voyelles.
      Il me semble que les numéros de série des appareils n’utilisent que des consonnes et des chiffres.
  • L’encodage devrait dépendre de l’utilisateur. Base32, en particulier Crockford et RFC 4648, est pratique pour des représentations courtes, avec des alphabets non ambigus et de bonnes raisons à cela.
    Mais si l’utilisateur doit le prononcer à voix haute, une représentation par liste de mots comme dans s/key RFC 1751, du type « TIDE ITCH SLOW REIN RULE MOT », peut être préférable.
    Il ne faut pas créer sa propre liste de mots. Les pièges cachés sont sans fin : expressions idiomatiques, homophones, dialectes, etc. Mieux vaut éviter de provoquer involontairement une catastrophe du genre « wet clam butterfly ».

    • Malheureusement, cet exemple peut aussi s’entendre comme « TIED HITCH SLOE REIGN RULE MOW ». Avec seulement 2 bits de parité, on ne peut même pas être sûr que ce décodage soit erroné.
      La RFC 1751 [0], d’où vient cet exemple, ne visait pas un encodage destiné à une transmission orale ; son objectif était de permettre aux utilisateurs de « lire, mémoriser et saisir » plus facilement.
      Pour une transmission orale entre spécialistes, se limiter aux 26 majuscules et s’appuyer sur l’alphabet phonétique de l’OTAN est un choix raisonnable. Mais obtenir un code auprès d’utilisateurs non formés, dans un environnement oral bruité, reste un problème non résolu.
      [0] https://datatracker.ietf.org/doc/html/rfc1751
    • Il faut sans doute tenir compte du fait que cela date de 1994, mais cela reste une RFC assez ridiculement mauvaise.
      Le passage « il faut utiliser l’algorithme de condensat de message à clé MD5, qui est suffisamment robuste » fait déjà sourire.
      Jusqu’à « la plupart des gens ont du mal à les lire, les mémoriser et les saisir », ça allait, puis cela bascule vers « les mots anglais sont beaucoup plus faciles à mémoriser et à saisir ». Le problème, c’est que la plupart des gens ne connaissent pas l’anglais ; on pourrait se dire qu’il suffit de changer la liste de mots, mais non : « pour des raisons d’interopérabilité, il n’est pas souhaitable d’avoir des dictionnaires distincts selon les langues ».
      Au final, l’idée semble être que, puisque le monde entier a appris les 26 lettres de l’alphabet anglais, ajouter quelques mots ne pose pas de problème ; sauf que dans char Wp[2048][4] = […], on ne trouve pas des mots courants adaptés aux débutants, mais des choses comme « WAD, BESS, MERT… ». On y voit même « ORR? AGEE EGAN HAAS!! » et « GAUL FLAM! DRAB! ».
    • Je me demande comment on appelle ce genre d’ID.
  • Cette discussion me rappelle quelque chose. Un jour où j’étais malade, pour oublier que j’avais mal partout, j’ai créé un petit module jouet faisant de l’arithmétique en base arbitraire ; c’était simple, alors je l’ai mis sur CPAN.
    Ce module, c’est https://metacpan.org/pod/Math::Fleximal.
    Parmi toutes les petites choses que j’ai faites, je pensais que celle-ci ne recevrait jamais de demande de support, mais c’est pourtant arrivé. La raison : j’avais inclus un exemple qui convertissait de l’hexadécimal en code alphanumérique, et quelqu’un avait eu la brillante idée de l’utiliser tel quel pour transformer de longs nombres en codes plus lisibles.
    Le module fonctionnait bien, mais le fait qu’il soit entré en production quelque part m’a paru assez ahurissant.

  • L’article insiste sur le fait qu’il faut éviter les caractères difficiles à distinguer même à la main, mais le tableau d’exemple contient le chiffre 7. J’ai vu un nombre incalculable de cas où il était difficile de distinguer le 7 et le 1 de quelqu’un.
    Mettre une barre au 7 aide, mais beaucoup de gens ne l’écrivent pas ainsi ; il arrive donc qu’on ne sache pas avec certitude s’il s’agit d’un 7 ou d’un 1 avec empattement.

    • L’article mentionne aussi « B » (Bravo) et « P » (Papa), difficiles à distinguer à l’oreille, mais il omet « F » (Foxtrot) et « S » (Sierra), qui se ressemblent bien plus.
      Parfois, les deux sont presque impossibles à distinguer. On peut utiliser l’alphabet OTAN/aéronautique standard (Alpha, Bravo, Charlie, Delta...), mais si la clientèle n’est pas très strictement limitée, cela n’aide pas beaucoup. Il vaut mieux éviter aussi ce genre de combinaisons.
      Même si la chaîne d’ID devient un peu plus longue, maximiser la capacité à lire, prononcer et entendre les caractères est bien préférable, et fait gagner beaucoup plus de temps et évite beaucoup plus d’agacement.
    • Je n’ai jamais vu un 1 manuscrit ressembler à un 7. En général, ce sont I ou l qui se confondent avec 1.
      Je me demande dans quel style d’écriture manuscrite le 1 devient proche du 7. La barre horizontale supérieure du 7 me semble déjà suffisante pour les distinguer.
    • Cela n’apparaissait pas au début, mais dans la section « dictionnaire visuellement ambigu », 1 et 7 sont tous les deux absents.
  • Si l’on utilise à la fois majuscules et minuscules, on finira tôt ou tard par se faire piéger par un système ou un protocole tiers insensible à la casse.
    J’ai déjà vu un système commercial qui permettait aux utilisateurs de choisir des ID sensibles à la casse, autorisant donc iD et id comme deux valeurs distinctes, mais qui, lorsqu’on recherchait un ID inexistant, effectuait une correspondance sans tenir compte de la casse et renvoyait les mauvaises données.
    Quand j’ai signalé ce bug, on m’a répondu que c’était une « fonctionnalité de confort ».

  • Sur Nintendo Switch, quand on saisissait un numéro de série de DLC, les touches correspondant aux caractères ambigus étaient désactivées sur le clavier à l’écran, et j’ai trouvé que c’était une assez bonne expérience utilisateur
    Cela signifie que les numéros de série sont générés dès le départ sans caractères ambigus. Je ne sais pas très bien si cette UX est intégrée au système d’exploitation, ou si elle n’existait que dans le jeu auquel je jouais, Mario + Rabbids Sparks of Hope

  • Le gestionnaire de mots de passe open source KeepassXC utilise des couleurs pour rendre les mots de passe plus lisibles. Chaque type de caractère — majuscules, minuscules, chiffres, symboles — a sa propre couleur
    C’est une idée toute simple, mais elle aide beaucoup, surtout avec des mots de passe aléatoires, même quand on utilise déjà une police très lisible

    • Bitwarden utilise aussi une police non ambiguë et trois couleurs. Les lettres sont dans la couleur par défaut, les chiffres en bleu et les symboles en rouge, et c’est vraiment très bien
      J’ai du mal à comprendre qu’un logiciel centré sur les mots de passe puisse accepter d’afficher les caractères dans une police ambiguë sans aucune distinction de couleur
    • Dans le générateur de mots de passe de KeepassXC, on peut aussi ajouter facilement une liste de caractères exclus
      Le moment où, en saisissant un long mot de passe avec une interface du genre télécommande de TV, on se rend compte qu’on a confondu l1|I est tellement rageant que je les exclus moi-même
    • En tant que personne daltonienne, je n’aime pas cette idée
  • C’était agréable à lire, parce que l’article traite d’un problème que je rencontre souvent au quotidien
    Chaque fois que je note sur papier des codes de secours d’authentification à deux facteurs, je suis inquiet quand je tombe sur des caractères comme o/0, v/u, 5/S. Du coup, je les écris volontairement avec de petites fioritures pour qu’ils se distinguent
    La partie sur la « similarité phonétique » m’a rappelé le moment de choisir un mot de passe Wi-Fi. Je voulais un mot courant, avec plusieurs consonnes, qu’on puisse partager en une seule phrase sans ambiguïté et qu’un élève de CE2 puisse épeler ; j’ai finalement choisi « vacation »

    • Ma règle consiste à mettre un point sous tous les chiffres. Ça règle les problèmes du type 5/S, 0/O, 8/B. Les paires réellement problématiques dépendent de l’écriture manuscrite de chacun
      Si je ne suis vraiment pas sûr, j’ajoute aussi l’alphabet OTAN/aéronautique [1]. Par exemple, s’il y a un U, je pars du U et j’écris Uniform en diagonale
      Il faut juste un peu de discipline. Je fais ça depuis plus de dix ans et je n’ai jamais perdu un code 2FA
      [1] Les pinaillages sur la différence réelle entre les codes OTAN et aéronautiques peuvent être envoyés sans risque vers /dev/null
    • J’ai du mal à croire qu’il y ait des gens qui écrivent ce genre de choses à la main sur du papier
      Le cerveau devient le goulot d’étranglement
  • J’aime ce genre de discussion. Ce n’est peut-être pas un sujet de pointe ni particulièrement excitant, mais il y a beaucoup de sens et de valeur à rendre la vie plus facile, à la fois pour les humains et pour les machines
    Ce sont aussi des choses qui relèvent des bonnes pratiques : quand elles sont bien faites, justement, personne ne les remarque. C’est dommage que le soin et la sincérité apportés aux détails soient rangés dans la catégorie de « ce qui devrait aller de soi » et ne soient donc pas vraiment salués

  • Pour signaler une erreur dans l’article : dans 9qg6G8B2Z5SIl170O (ariel), le nom de la police n’est pas Ariel mais Arial. La petite sirène n’a rien à faire ici

    • Exact. Et pour cette partie, une capture d’écran ou une police web aurait sans doute été préférable
      Sous Linux, la plupart des lignes se ressemblent exactement
    • L’article est open source, on peut contribuer à le corriger
      https://github.com/gajus/gajus-com/blob/main/src/blogPosts/2...
      J’ai corrigé la faute de frappe