4 Punkte von GN⁺ 2024-04-24 | 3 Kommentare | Auf WhatsApp teilen
  • Bei Vorgängen, in denen Menschen IDs lesen und weitergeben – etwa beim Melden von Bugs, Eingeben von Rabattcodes oder Verfolgen von Sendungen –, führt visuelle Mehrdeutigkeit wie O/0 oder I/l/1/7 leicht zu Eingabefehlern
  • Verwechslungen nehmen je nach Schriftart und Handschrift zu, und Kombinationen mit unscharfer Unterscheidbarkeit wie 5/S, 2/Z, 8/B, 6/G, 9/q/g tauchen wiederholt auf
  • Bei IDs, mit denen Menschen direkt arbeiten – etwa im Kundensupport, bei Fehler-IDs oder Produkt-IDs –, ist die Wahl eines gut lesbaren Zeichensatzes für die praktische Nutzbarkeit oft wichtiger als ein möglichst großer Zeichenvorrat
  • Mit Groß-/Kleinschreibung lassen sich bei 5-stelligen IDs 418,195,493 Kombinationen erzeugen, ohne Unterscheidung nur 5,153,632; deshalb ist ein Kompromiss zwischen Länge und Sicherheit nötig
  • IDs mit Groß-/Kleinschreibung lassen sich zwar kürzer halten, aber einige Drittanbieter-Systeme oder Protokolle arbeiten möglicherweise ohne Unterscheidung von Groß- und Kleinschreibung, was bei der Integration Probleme verursachen kann

Zeichenverwechslungen bei menschenlesbaren IDs

  • Wenn IDs in Systeminteraktionen wie Bug-Reports, der Eingabe von Rabattcodes oder der Sendungsverfolgung notiert oder weitergegeben werden, können vermeidbare Zeichenverwechslungen die User Experience beeinträchtigen
  • Typische Kombinationen visuell mehrdeutiger Zeichen sind:
    • O / 0: Bei einer 0 ohne Schrägstrich oder Punkt können der Buchstabe O und die Ziffer 0 ähnlich aussehen
    • I / l / 1 / 7: Großes I, kleines l, die Ziffern 1 und 7 sind in vielen Druckschriften und in Handschrift schwer zu unterscheiden
    • 5 / S, 2 / Z, 8 / B, 6 / G, 9 / q / g: Können in bestimmten Schriften, stilisierten Fonts oder Handschrift verwechselt werden
  • Die Beispielzeichenfolge 9qg6G8B2Z5SIl170O wird in verschiedenen Systemschriften wie Arial, Helvetica, Courier, Times, Verdana, Georgia, Tahoma, Impact und Comic Sans zum Vergleich herangezogen
  • Manche Kombinationen wie I und l bleiben in vielen Schriftarten dauerhaft mehrdeutig, und Kombinationen wie 9qg werden beim handschriftlichen Schreiben noch leichter verwechselt
    • ID-Typen, bei denen das Problem besonders groß wird

    • Rabattcodes, die im Kundensupport ausgetauscht werden
    • Tracking-Codes für Versand und Logistik
    • Fehler-IDs, die für Reproduktion und Supportanfragen benötigt werden
    • Produkt-IDs zur Produktidentifikation

Der Kompromiss zwischen Groß-/Kleinschreibung und Zeichensatz

  • Ob eine ID abc und ABC als denselben Wert behandelt, sollte bei der Festlegung der Generierungsregeln mitentschieden werden
  • Wenn Groß- und Kleinschreibung unterschieden und visuell mehrdeutige Zeichen ausgeschlossen werden, bleiben 53 mögliche Zeichen
  • Ohne Unterscheidung von Groß- und Kleinschreibung sinkt die Zahl auf 22 mögliche Zeichen
  • Die Anzahl möglicher Kombinationen je nach ID-Länge:
    • 5 Zeichen, mit Groß-/Kleinschreibung: 53^5 = 418,195,493
    • 5 Zeichen, ohne Groß-/Kleinschreibung: 22^5 = 5,153,632
    • 8 Zeichen, mit Groß-/Kleinschreibung: 53^8 = 62,259,690,411,361
    • 8 Zeichen, ohne Groß-/Kleinschreibung: 22^8 = 54,875,873,536
  • Letztlich geht es um die Balance zwischen kurzen, aber potenziell verwechselbaren IDs und längeren, dafür leichter lesbaren IDs
  • Wer Groß- und Kleinbuchstaben zugleich verwendet, kann irgendwann auf unerwartetes Verhalten in Drittanbieter-Systemen oder Protokollen stoßen, die nicht zwischen Groß- und Kleinschreibung unterscheiden
    • Ein kommerzielles System erlaubte es Nutzern, iD und id als unterschiedliche IDs zu wählen, führte bei der Abfrage einer nicht existierenden ID aber ein Matching ohne Groß-/Kleinschreibung aus und lieferte dadurch falsche Daten zurück
    • Auf den Bug kam die Antwort, dieses Verhalten diene der „Bequemlichkeit“

Nicht nur einzelne Zeichen, auch Kombinationen können problematisch sein

  • Auch Zeichenfolgen selbst können wie andere Zeichen wirken
    • rn kann wie m aussehen
    • vv kann wie w aussehen
  • Würde man aus diesem Grund massenhaft Zeichen ausschließen, würde der verfügbare Zeichensatz zu stark schrumpfen; realistischer ist es daher, bei der Generierung nur bestimmte Kombinationen zu vermeiden
  • In Situationen, in denen Codes mündlich übermittelt werden, kann man zusätzlich klangliche Ähnlichkeit berücksichtigen
    • Zum Beispiel können b und p beim Aussprechen ähnlich klingen

Bestehende Ansätze als Referenz

  • Crockfords Base32 dekodiert mehrdeutige Zeichen zum selben Wert und berücksichtigt auch das Problem unbeabsichtigter obszöner Ausdrücke
  • Open Location Code verwendet den Zeichensatz 23456789CFGHJMPQRVWX
    • Dieser Zeichensatz wurde so gewählt, dass visuell mehrdeutige Zeichen und auch die Schreibweise gewöhnlicher Wörter in natürlichen Sprachen vermieden werden
    • Enthält allerdings sowohl 6 und G als auch 9 und Q

3 Kommentare

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

Dass dabei sogar die Aussprache berücksichtigt wurde, ist wirklich erstaunlich.

 
GN⁺ 2024-04-24
Hacker-News-Kommentare
  • Bei der Arbeit wurden einmal Seriennummern auf mehrere Millionen Geräte gedruckt und ausgeliefert, ohne auch nur ein einziges leicht verwechselbares Zeichen oder eine leicht verwechselbare Ziffer auszuschließen, sodass die Kunden große Mühe hatten, sie korrekt zu lesen.
    Ich musste ein Regex-Skript schreiben, das aus dem vom Kunden genannten Wert alle denkbaren Tippfehler-Kombinationen erzeugte und nur die Treffer anzeigte, die zur Fabrikdatenbank passten; anschließend wurden andere Informationen wie das Datum abgeglichen, um die tatsächliche Seriennummer zu erschließen.
    Noch ironischer war, dass sich einige Stellen nie änderten und an manchen Positionen zur Kennzeichnung des Werks nur 0, 1 und 2 gebraucht wurden, sodass man von vornherein nicht den gesamten Zeichensatz benötigt hätte. Es wirkte fast so, als hätte man geglaubt, 8 Billiarden Geräte zu bauen

    • Es ist oft nützlich oder wird zumindest als nützlich angesehen, zu verhindern, dass Geschäftsinformationen aus Seriennummern durchsickern.
      Wenn man ein Produkt zum Beispiel mit fortlaufenden Nummern wie 1, 2, 3 versieht, kann man schon mit einer kleinen Stichprobe die Gesamtverkaufszahlen ziemlich leicht abschätzen. Es kann auch helfen, Missbrauch wie erschlichene Rückerstattungen zu verhindern, indem gültige Seriennummern schwerer zu erraten sind.
      Natürlich kann man trotz solcher Bedenken trotzdem Maßnahmen treffen, um schwer lesbare Zeichen zu vermeiden, und wenn überhaupt jemand über das Nummernschema nachgedacht hat, hätte man dieses Problem eher sehen müssen. Wahrscheinlicher ist, dass sich jemand 30 Sekunden Gedanken gemacht und gesagt hat: „So viele Stellen werden uns nie ausgehen, fertig.“
    • Wenn ich so darüber nachdenke, könnte das auch der Grund oder zumindest ein Faktor dafür sein, warum Apple-Seriennummern keine Vokale enthalten.
      In Geräteseriennummern scheinen nur Konsonanten und Ziffern verwendet zu werden
  • Die Kodierung sollte vom Benutzer abhängen. Base32, insbesondere Crockford und RFC 4648, eignet sich gut für kurze Darstellungen und hat einen überzeugenden Grund für ein nicht mehrdeutiges Alphabet.
    Wenn der Benutzer den Wert aber laut aussprechen muss, ist eine Wortlisten-Darstellung wie bei s/key RFC 1751 mit etwas wie „TIDE ITCH SLOW REIN RULE MOT“ vielleicht besser.
    Man sollte so eine Wortliste nicht selbst bauen. Es gibt unendlich viele versteckte Fallen wie Redewendungen, Homophone und Dialekte. Man sollte nicht versehentlich einen Großunfall wie „wet clam butterfly“ erzeugen

    • Leider könnte dieses Beispiel auch als „TIED HITCH SLOE REIGN RULE MOW“ verstanden werden. Mit nur 2 Paritätsbits kann man noch nicht einmal sicher sagen, dass diese Dekodierung falsch ist.
      RFC 1751 [0], aus dem dieses Beispiel stammt, war nicht als Kodierung für die mündliche Übermittlung gedacht, sondern soll es dem Benutzer erleichtern, etwas zu „lesen, zu merken und einzugeben“.
      Für die mündliche Übermittlung unter Fachleuten ist die Wahl von nur 26 Großbuchstaben und die Verwendung des NATO-Buchstabieralphabets plausibel. Aber das Problem, ungeschulte Nutzer in einer lauten mündlichen Umgebung einen Code entgegennehmen zu lassen, ist weiterhin ungelöst.
      [0] https://datatracker.ietf.org/doc/html/rfc1751
    • Man sollte berücksichtigen, dass das von 1994 ist, aber es ist trotzdem ein geradezu lächerlich schlechtes RFC.
      Schon die Stelle „the keyed message digest algorithm MD5 should be used, and is sufficiently strong“ ist zum Lachen.
      Bis „für die meisten Menschen schwer zu lesen, zu merken und einzugeben“ ist es noch gut, dann geht es zu „englische Wörter sind für Menschen viel leichter zu merken und einzugeben“. Das Problem, dass die meisten Menschen kein Englisch können, bleibt, aber ich dachte, man könnte einfach die Wortliste austauschen; stattdessen heißt es, „wegen der Interoperabilität seien sprachspezifische Wörterbücher nicht wünschenswert“.
      Am Ende läuft es auf die Haltung hinaus, dass ohnehin die ganze Welt das 26-buchstabige englische Alphabet gelernt habe und man deshalb auch noch ein paar Wörter hinzufügen könne, aber in char Wp[2048][4] = […] stehen keine geläufigen Wörter für Anfänger, sondern Dinge wie „WAD, BESS, MERT…“. Sogar „ORR? AGEE EGAN HAAS!!“ und „GAUL FLAM! DRAB!“ kommen vor
    • Ich frage mich, wie man diese Art von IDs nennt
  • Diese Geschichte erinnerte mich an etwas von früher. An einem Krankheitstag habe ich, um mich von den Schmerzen abzulenken, ein Spielzeugmodul für Arithmetik in beliebigen Basen gebaut, und weil es einfach war, habe ich es auf CPAN hochgeladen.
    Das Modul ist https://metacpan.org/pod/Math::Fleximal.
    Von all den kleinen Dingen, die ich gebaut habe, dachte ich, dass dafür ganz sicher nie eine Supportanfrage kommen würde, aber genau das geschah. Der Grund war, dass ich ein Beispiel eingefügt hatte, das Hexadezimalwerte in alphanumerische Codes umwandelt, und irgendjemand auf die tolle Idee kam, es unverändert dafür zu verwenden, lange Zahlen in besser lesbare Codes zu verwandeln.
    Das Modul funktionierte zwar gut, aber die Tatsache, dass es irgendwo in Production gelandet ist, war ziemlich absurd

  • Der Artikel betont, dass man auch Zeichen vermeiden sollte, die in Handschrift schwer zu unterscheiden sind, aber in der Beispieltabelle steht die Ziffer 7. Ich habe unzählige Fälle erlebt, in denen die 7 von jemandem kaum von einer 1 zu unterscheiden war.
    Ein Querstrich auf der 7 hilft, aber viele Menschen schreiben sie nicht so, sodass man manchmal nicht sicher sein kann, ob es eine 7 oder eine 1 mit Serife ist

    • Im Artikel wurden klanglich schwer zu unterscheidende Zeichen wie „B“ (Bravo) und „P“ (Papa) erwähnt, aber das noch ähnlicher klingende „F“ (Foxtrot) und „S“ (Sierra) fehlt.
      Die beiden sind manchmal fast nicht zu unterscheiden. Man könnte das NATO-/Luftfahrt-Buchstabieralphabet (Alpha, Bravo, Charlie, Delta...) verwenden, aber außer bei einer sehr eng begrenzten Zielgruppe hilft das nicht viel. Solche Kombinationen sollte man besser ebenfalls vermeiden.
      Auch wenn der ID-String dadurch etwas länger wird, ist es viel besser, die Les-, Sprech- und Hörbarkeit der Zeichen zu maximieren; das spart deutlich mehr Zeit und Frust
    • Ich habe noch nie erlebt, dass eine handschriftliche 1 wie eine 7 aussieht. Normalerweise werden I oder l mit 1 verwechselt.
      Ich frage mich, bei welchem Handschriftstil eine 1 einer 7 ähnlich wird. Der obere Querstrich der 7 sollte sie doch ausreichend unterscheiden
    • Im vorderen Teil fehlte es zwar, aber im Abschnitt „visually ambiguous dictionary“ stehen 1 und 7 tatsächlich beide nicht
  • Wenn man sowohl Groß- als auch Kleinbuchstaben verwendet, läuft man irgendwann Gefahr, von einem nicht zwischen Groß- und Kleinschreibung unterscheidenden Fremdsystem oder Protokoll erwischt zu werden.
    Ich habe tatsächlich einmal ein kommerzielles System gesehen, in dem Benutzer IDs mit Groß-/Kleinschreibung unterscheiden durften, also iD und id als verschiedene Werte zulässig waren, das aber bei der Abfrage einer nicht existierenden ID eine case-insensitive Übereinstimmung machte und dadurch völlig falsche Daten zurückgab.
    Als ich diesen Bug meldete, lautete die Antwort: „eine Komfortfunktion“

  • Bei der Eingabe einer DLC-Seriennummer auf der Nintendo Switch waren mehrdeutige Zeichentasten auf der Bildschirmtastatur deaktiviert; das wirkte wie eine ziemlich gute User Experience.
    Das bedeutet, dass die Seriennummern von vornherein ohne mehrdeutige Zeichen erzeugt werden. Ich weiß allerdings nicht, ob diese UX ins Betriebssystem eingebaut ist oder nur in dem Spiel vorkam, das ich gerade spielte, nämlich Mario + Rabbids Sparks of Hope

  • Der Open-Source-Passwortmanager KeePassXC verwendet Farben, um Passwörter besser lesbar zu machen. Verschiedene Zeichentypen wie Großbuchstaben, Kleinbuchstaben, Zahlen und Symbole bekommen jeweils unterschiedliche Farben.
    Eine sehr einfache Idee, aber gerade bei zufälligen Passwörtern hilft sie enorm, selbst wenn bereits eine gut lesbare Schriftart verwendet wird

    • Bitwarden nutzt ebenfalls eine nicht mehrdeutige Schriftart und drei Farben. Buchstaben in der Standardfarbe, Zahlen in Blau und Symbole in Rot – wirklich gut.
      Schwer nachzuvollziehen, warum Software mit Passwortfokus es zulässt, Zeichen ohne jede farbliche Unterscheidung in einer mehrdeutigen Schriftart zu rendern
    • Im Passwortgenerator von KeePassXC lässt sich auch leicht eine Liste ausgeschlossener Zeichen hinzufügen.
      Ich schließe sie selbst aus, weil es mich wahnsinnig macht, wenn ich über eine TV-Fernbedienungs-Oberfläche ein langes Passwort eingebe und dann merke, dass ich l1|I verwechselt habe
    • Aus Sicht von Menschen mit Farbsehschwäche gefällt mir diese Idee nicht
  • Angenehm zu lesen, weil der Artikel ein Problem behandelt, dem man im Alltag oft begegnet.
    Jedes Mal, wenn ich Backup-Codes für die Zwei-Faktor-Authentifizierung auf Papier notiere, werde ich nervös, sobald ich über Zeichen wie o/0, v/u oder 5/S stolpere. Deshalb schreibe ich solche Zeichen absichtlich leicht verziert, damit sie sich unterscheiden.
    Der Teil über „klangliche Ähnlichkeit“ erinnerte mich daran, wie ich einmal ein WLAN-Passwort ausgewählt habe. Ich wollte ein gängiges Wort mit mehreren Konsonanten, das man in einem Satz weitergeben kann, ohne dass es mehrdeutig wird, und das sogar ein Drittklässler buchstabieren könnte; am Ende fiel die Wahl auf „vacation“

    • Meine Regel ist, unter jede Zahl einen Punkt zu setzen. Damit lösen sich Probleme wie 5/S, 0/O und 8/B. Welche Paare tatsächlich problematisch sind, hängt von der jeweiligen Handschrift ab.
      Wenn ich mir wirklich nicht sicher bin, schreibe ich zusätzlich das NATO-/Fliegeralphabet [1] dazu. Wenn dort zum Beispiel ein U steht, beginne ich beim U und schreibe diagonal „Uniform“ dazu.
      Es braucht nur ein wenig Disziplin. Ich mache das seit über zehn Jahren und habe noch nie einen 2FA-Code verloren.
      [1] Pedanterie über die tatsächlichen Unterschiede zwischen NATO- und Fliegercode kann bedenkenlos nach /dev/null verschoben werden
    • Ich kann kaum glauben, dass es Leute gibt, die so etwas per Hand auf Papier schreiben.
      Der Kopf ist der Flaschenhals
  • Ich mag solche Gespräche. Es ist vielleicht kein hochmodernes oder besonders aufregendes Thema, aber es hat erheblichen Wert und Wirkung dabei, das Leben für Menschen wie auch für Maschinen leichter zu machen.
    Das gehört auch zu den Best Practices, die bei guter Umsetzung gerade deshalb niemand bemerkt. Schade, dass Sorgfalt und Aufrichtigkeit im Detail oft einfach als „so sollte es selbstverständlich sein“ abgetan werden und daher kein besonderes Lob bekommen

  • Wenn man auf einen Fehler im Artikel hinweisen will: Bei 9qg6G8B2Z5SIl170O (ariel) heißt die Schriftart nicht Ariel, sondern Arial. Die kleine Meerjungfrau kommt hier nicht vor

    • Stimmt. Und an der Stelle wäre ein Screenshot oder die Verwendung einer Webschrift vermutlich besser gewesen.
      Unter Linux sehen die meisten Zeilen gleich aus
    • Da der Artikel Open Source ist, kann man selbst zur Korrektur beitragen.
      https://github.com/gajus/gajus-com/blob/main/src/blogPosts/2...
      Den Tippfehler habe ich bereits korrigiert