4 puntos por GN⁺ 2024-04-24 | 3 comentarios | Compartir por WhatsApp
  • En procesos donde una persona tiene que leer y comunicar un ID, como reportes de bugs, ingreso de códigos de descuento o seguimiento de envíos, la ambigüedad visual de caracteres como O/0 o I/l/1/7 puede convertirse fácilmente en errores de captura
  • La confusión aumenta según la tipografía y la escritura a mano, y aparecen repetidamente combinaciones difíciles de distinguir como 5/S, 2/Z, 8/B, 6/G, 9/q/g
  • En ID que las personas manejan directamente, como atención al cliente, ID de errores o ID de producto, suele ser más importante para la calidad real de uso elegir un conjunto de caracteres fácil de leer que simplemente usar un conjunto grande de caracteres
  • Si se distingue entre mayúsculas y minúsculas, un ID de 5 caracteres puede generar 418,195,493 combinaciones, pero si no se distingue, baja a 5,153,632, así que hace falta un equilibrio entre longitud y seguridad
  • Los ID sensibles a mayúsculas y minúsculas ayudan a hacerlos más cortos, pero algunos sistemas o protocolos de terceros pueden funcionar de forma insensible a mayúsculas y minúsculas, lo que puede causar problemas en la integración

Confusión de caracteres en ID leídos por personas

  • Cuando un ID se escribe o se transmite en interacciones del sistema, como reportes de bugs, ingreso de códigos de descuento o seguimiento de envíos, la confusión entre caracteres que se puede evitar puede arruinar la experiencia de usuario
  • Las combinaciones representativas de caracteres visualmente ambiguos son las siguientes
    • O / 0: en un 0 sin barra ni punto, la letra O y el número 0 pueden verse parecidos
    • I / l / 1 / 7: la I mayúscula, la l minúscula, el 1 y el 7 pueden ser difíciles de distinguir en muchos impresos y en escritura a mano
    • 5 / S, 2 / Z, 8 / B, 6 / G, 9 / q / g: pueden confundirse en ciertas tipografías, fuentes estilizadas o escritura a mano
  • La cadena de ejemplo 9qg6G8B2Z5SIl170O se usa como referencia de comparación en varias fuentes del sistema, como Arial, Helvetica, Courier, Times, Verdana, Georgia, Tahoma, Impact y Comic Sans
  • Algunas combinaciones, como I y l, pueden seguir viéndose ambiguas en muchas fuentes, y otras como 9qg pueden resultar todavía más confusas al escribirlas a mano
  • Tipos de ID donde el problema se agrava especialmente

    • códigos de descuento intercambiados por atención al cliente
    • códigos de seguimiento usados en envíos o logística
    • ID de errores necesarios para reproducir problemas y atender consultas
    • ID de producto usados para identificación de productos

Equilibrio entre sensibilidad a mayúsculas y minúsculas y conjunto de caracteres

  • Al definir las reglas de generación, también hay que decidir si un ID como abc y ABC se considerará el mismo valor o no
  • Si se distingue entre mayúsculas y minúsculas y además se excluyen los caracteres visualmente ambiguos, quedan 53 caracteres disponibles
  • Si no se distingue entre mayúsculas y minúsculas, los caracteres disponibles se reducen a 22
  • La cantidad de combinaciones posibles según la longitud del ID es la siguiente
    • 5 caracteres, sensible a mayúsculas y minúsculas: 53^5 = 418,195,493
    • 5 caracteres, insensible a mayúsculas y minúsculas: 22^5 = 5,153,632
    • 8 caracteres, sensible a mayúsculas y minúsculas: 53^8 = 62,259,690,411,361
    • 8 caracteres, insensible a mayúsculas y minúsculas: 22^8 = 54,875,873,536
  • Al final, la decisión es un equilibrio entre ID cortos pero con más riesgo de confusión e ID más largos pero más fáciles de leer
  • Si se usan tanto mayúsculas como minúsculas, tarde o temprano puede aparecer un comportamiento inesperado en sistemas o protocolos de terceros que no distinguen mayúsculas de minúsculas
    • Un sistema comercial permitía que el usuario eligiera iD e id como ID distintos, pero al consultar un ID inexistente hacía una coincidencia insensible a mayúsculas y minúsculas y devolvía datos incorrectos
    • La respuesta a ese bug fue que era un comportamiento pensado “por conveniencia”

A veces hay que evitar no solo caracteres, sino también combinaciones

  • También hay casos en los que una combinación de caracteres se ve como si fuera otro carácter
    • rn puede verse como m
    • vv puede verse como w
  • Excluir demasiados caracteres solo por este motivo puede reducir demasiado el conjunto disponible, así que puede ser más realista evitar solo combinaciones específicas en la etapa de generación
  • En situaciones donde el ID se transmite verbalmente, también se puede considerar la similitud fonética
    • Por ejemplo, b y p pueden sonar parecidos al decirlos en voz alta

Enfoques existentes que vale la pena revisar

  • Base32 de Crockford decodifica caracteres ambiguos como si fueran el mismo valor y también considera el problema de expresiones obscenas accidentales
  • Open Location Code usa el conjunto de caracteres 23456789CFGHJMPQRVWX
    • Este conjunto fue elegido para evitar caracteres visualmente ambiguos y también la ortografía de palabras de lenguas comunes
    • Aun así, incluye tanto 6 y G como 9 y Q

3 comentarios

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

Es realmente asombroso que incluso hayan tenido en cuenta la pronunciación.

 
GN⁺ 2024-04-24
Opiniones en Hacker News
  • En el trabajo enviamos millones de dispositivos con números de serie, pero no excluimos ningún carácter ni número confuso, y los clientes tuvieron muchísimos problemas para leerlos correctamente.
    Tuve que crear un script con expresiones regulares que generaba todas las combinaciones posibles de errores tipográficos a partir del valor que decía el cliente y mostraba solo las que coincidían con la base de datos de la fábrica; luego comparábamos otra información, como la fecha, para inferir el número de serie real.
    Lo más irónico es que algunos dígitos nunca cambiaban, y en cierta posición solo hacía falta usar 0, 1 o 2 para distinguir la fábrica, así que desde el principio no necesitábamos todo el conjunto de caracteres. Era como si hubiéramos creído que íbamos a fabricar 8 cuatrillones de unidades.

    • Muchas veces es útil, o al menos se considera útil, evitar que se filtre información comercial a través de los números de serie.
      Por ejemplo, si numeras los productos de forma secuencial como 1, 2, 3, con una muestra pequeña es bastante fácil estimar las ventas totales. Hacer que sea difícil adivinar números de serie válidos también puede ayudar a evitar abusos, como fraudes en reembolsos.
      Claro que, aun con esas preocupaciones, se puede tomar la medida de evitar caracteres difíciles de leer; de hecho, si eso significa que alguien está pensando qué sistema de numeración usar, debería haber sido más consciente de estos problemas. En la práctica, parece más probable que alguien lo haya pensado unos 30 segundos y haya dicho: “si usamos esta cantidad de posiciones, nunca se nos van a acabar, listo”.
    • Ahora que lo pienso, esta podría ser también la razón —o al menos un factor— por la que los números de serie de Apple no tienen vocales.
      Parece que en los números de serie de los dispositivos solo usan consonantes y números.
  • La codificación debería depender del usuario. Base32, en especial Crockford y RFC 4648, es buena para representar de forma breve y tiene alfabetos no ambiguos y buenas razones para ello.
    Pero si el usuario tiene que decirlo en voz alta, quizá convenga más una representación con lista de palabras como s/key RFC 1751: “TIDE ITCH SLOW REIN RULE MOT”.
    No hagas tu propia lista de palabras. Hay una cantidad interminable de trampas ocultas: modismos, homófonos, dialectos, etc. No quieras crear sin querer un desastre tipo “wet clam butterfly”.

    • Lamentablemente, ese ejemplo también podría oírse como “TIED HITCH SLOE REIGN RULE MOW”. Con solo 2 bits de paridad, ni siquiera se puede tener certeza de que esa decodificación sea incorrecta.
      El RFC 1751 [0], de donde sale este ejemplo, no estaba pensado como una codificación para transmisión oral, sino para que a los usuarios les resultara más fácil “leer, recordar e ingresar” los datos.
      Si la transmisión oral es entre expertos, tiene sentido usar solo las 26 mayúsculas y apoyarse en el alfabeto fonético de la OTAN. Pero lograr que usuarios sin entrenamiento reciban un código en un entorno oral con mucho ruido sigue siendo un problema sin resolver.
      [0] https://datatracker.ietf.org/doc/html/rfc1751
    • Hay que considerar que es de 1994, pero aun así es un RFC bastante ridículamente malo.
      Ya da risa desde la parte que dice que “debe usarse el algoritmo de resumen de mensajes con clave MD5, y es suficientemente fuerte”.
      Venía bien hasta “a la mayoría de las personas les resulta difícil leerlos, recordarlos e ingresarlos”, pero luego pasa a “las palabras en inglés son mucho más fáciles de recordar e ingresar para las personas”. Está el problema de que la mayoría de las personas no sabe inglés; pensé que tal vez bastaría con cambiar la lista de palabras, pero dice que “por interoperabilidad, no es deseable tener diccionarios separados por idioma”.
      Al final es como decir que, como todo el mundo ya aprendió las 26 letras del alfabeto inglés, agregar unas cuantas palabras no pasa nada, pero dentro de char Wp[2048][4] = […] no hay palabras comunes adecuadas para principiantes, sino cosas como “WAD, BESS, MERT…”. Incluso aparecen “ORR? AGEE EGAN HAAS!!” y “GAUL FLAM! DRAB!”.
    • Me pregunto cómo se llaman los ID de este tipo.
  • Esto me recuerda algo de hace tiempo. Un día que estaba enfermo hice, para distraerme del malestar, un módulo de juguete para aritmética en bases arbitrarias; como era sencillo, lo subí a CPAN.
    Ese módulo es https://metacpan.org/pod/Math::Fleximal.
    De todas las cosas triviales que hice, pensé que esta jamás recibiría una solicitud de soporte, pero sí ocurrió. La razón fue que había incluido un ejemplo para convertir hexadecimal en códigos alfanuméricos, y a alguien se le ocurrió la brillante idea de usarlo tal cual para convertir números largos en códigos legibles.
    El módulo funcionaba bien, pero fue bastante absurdo enterarme de que eso había terminado en producción en algún lugar.

  • El artículo enfatiza que hay que evitar caracteres difíciles de distinguir incluso escritos a mano, pero en la tabla de ejemplo incluye el número 7. He tenido incontables situaciones en las que era difícil distinguir el 7 y el 1 de alguien.
    Ponerle una barra horizontal al 7 ayuda, pero mucha gente no lo escribe así, así que a veces cuesta saber si es un 7 o un 1 con serif.

    • El artículo también mencionaba “B” (Bravo) y “P” (Papa), que pueden ser difíciles de distinguir por sonido, pero omitía “F” (Foxtrot) y “S” (Sierra), que suenan mucho más parecidas.
      A veces casi no se distinguen. Se podría usar el alfabeto estándar OTAN/aeronáutico (Alpha, Bravo, Charlie, Delta...), pero si tu base de clientes no está extremadamente acotada, no ayuda demasiado. También conviene evitar estas combinaciones.
      Aunque la cadena de ID se vuelva un poco más larga, es mucho mejor maximizar la capacidad de leer, decir y escuchar los caracteres; ahorra mucho más tiempo y frustración.
    • Nunca me ha pasado que un 1 escrito a mano parezca un 7. Normalmente son I o l las que se confunden con 1.
      Me pregunto en qué estilo de escritura a mano el 1 se parece al 7. Con solo el trazo horizontal superior del 7 debería bastar para distinguirlo.
    • Aunque no aparecen en la parte inicial, en la sección “diccionario visualmente ambiguo” no están incluidos ni 1 ni 7.
  • Si usas tanto mayúsculas como minúsculas, tarde o temprano te va a afectar algún sistema o protocolo de terceros sin distinción entre mayúsculas y minúsculas.
    De hecho, he visto un sistema comercial que permitía a los usuarios elegir ID que distinguían mayúsculas y minúsculas, aceptando iD e id como valores distintos, pero que al consultar un ID inexistente hacía una coincidencia ignorando mayúsculas y minúsculas y devolvía datos equivocados.
    Cuando reporté este bug, respondieron que era una “función de conveniencia”.

  • Al ingresar un número de serie de DLC en Nintendo Switch, las teclas de caracteres ambiguos estaban desactivadas en el teclado en pantalla, y me pareció una experiencia de usuario bastante buena
    Eso significa que, desde un principio, los números de serie se generan sin caracteres ambiguos. No sé bien si esta UX está integrada en el sistema operativo o si solo estaba en el juego que estaba jugando, Mario + Rabbids Sparks of Hope

  • El gestor de contraseñas open source KeepassXC usa colores para que las contraseñas sean más legibles. La idea es usar un color distinto para cada tipo de carácter, como mayúsculas, minúsculas, números y símbolos
    Es una idea muy simple, pero ayuda mucho, especialmente con contraseñas aleatorias, incluso si ya se usa una fuente muy legible

    • Bitwarden también usa una fuente no ambigua y tres colores. Los caracteres van en el color predeterminado, los números en azul y los símbolos en rojo, y es realmente bueno
      Me cuesta entender que software centrado en contraseñas permita renderizar caracteres con una fuente ambigua y sin ninguna diferenciación por color
    • En el generador de contraseñas de KeepassXC también se puede agregar fácilmente una lista de caracteres excluidos
      Me da tanta rabia cuando estoy ingresando una contraseña larga en una interfaz como la de un control remoto de TV y me doy cuenta de que confundí l1|I, que directamente los excluyo
    • Como persona con daltonismo, no me gusta esta idea
  • Fue una buena lectura porque trata un problema que me encuentro a menudo
    Cada vez que escribo en papel códigos de respaldo de autenticación de dos factores, me pongo nervioso al pasar por caracteres como o/0, v/u, 5/S. Por eso empecé a escribir esos caracteres con pequeños adornos a propósito, para que se vean distintos
    La parte de la “similitud fonética” me recordó a cuando elijo una contraseña de wifi. Quería una palabra común que no fuera ambigua al compartirla en una sola oración, que hasta un niño de tercer grado de primaria pudiera deletrear y que tuviera varias consonantes, y al final elegí “vacation”

    • Mi regla es poner un punto debajo de todos los números. Así se resuelven problemas como 5/S, 0/O, 8/B. En la práctica, los pares problemáticos dependen de la letra manuscrita de cada quien
      Si de verdad no estoy seguro, también agrego el alfabeto NATO/aeronáutico [1]. Por ejemplo, si hay una U, escribo Uniform en diagonal empezando desde la U
      Solo hace falta un poco de disciplina. Llevo más de 10 años haciendo esto y nunca he perdido un código de autenticación de dos factores
      [1] Las objeciones quisquillosas sobre la diferencia real entre el código NATO y el aeronáutico pueden enviarse tranquilamente a /dev/null
    • Me cuesta creer que haya gente que escriba esto a mano en papel
      El cuello de botella es la cabeza
  • Me gustan estas conversaciones. Quizá no sean temas de vanguardia ni emocionantes, pero tienen bastante significado y fuerza para hacerles la vida más fácil tanto a las personas como a las máquinas
    Estas cosas también pertenecen al ámbito de las mejores prácticas, donde, si se hacen bien, más bien nadie las nota. Es una lástima que el cuidado y la sinceridad por los detalles se agrupen bajo “así debe ser” y no reciban elogios especiales

  • Para señalar un error del artículo: en 9qg6G8B2Z5SIl170O (ariel), el nombre de la fuente no es Ariel, sino Arial. La sirenita no aparece por aquí