Konzept: Zeichenverlust ist nicht Mojibake

11-Der deklarierte Zeichensatz ist eine Behauptung beschreibt den einen Schaden auf der Zeichensatzschicht: Die Deklaration in MSH-18 und die tatsächliche Kodierung fallen auseinander, und aus „Müller” wird „Müller”. Diese Seite beschreibt den zweiten, der dieselbe Schicht betrifft, im Ticket denselben Namen trägt („Umlautproblem”) und sich in jeder anderen Hinsicht gegenteilig verhält.

Eine v2-Nachricht ist dreifach kodiert

Wer sie liest, baut drei Schichten nacheinander ab. Jede ist woanders deklariert, jede kann für sich brechen, und keine merkt etwas vom Bruch der anderen.

#SchichtWo deklariertWas sie regeltBruchbild
1Zeichen ← BytesMSH-18 (Tabelle 0211), Default ASCIIwelche Bytefolge welches Zeichen bedeutetMojibake, Zeichenverlust
2Struktur ← ZeichenMSH-1 / MSH-2, positionell gelesenwelche Zeichen Struktur bedeuten statt TextFeld- und Komponentenversatz
3Text ← Struktur§ 2.7 Escape-Sequenzenwie ein Strukturzeichen doch Text sein darf, und wie ein Zeichen reist, das der Zeichensatz nicht kenntDatenverlust im Wert

Die Reihenfolge ist zwingend: Schicht 2 ist erst lesbar, wenn Schicht 1 aufgelöst ist, Schicht 3 erst nach Schicht 2. Ein Defekt auf Schicht 1 ist für alle darüberliegenden Prüfungen unsichtbar — sie arbeiten bereits mit dem Ergebnis.

Die zwei Schäden auf Schicht 1

Verfälschung (Mojibake)Verlust (Transkodierung)
UrsacheDeklaration ≠ tatsächliche KodierungZeichen existiert im Zielzeichensatz nicht
Bytesalle vorhanden, nur falsch gedeutetnicht mehr vorhanden
ErgebnisMüllerWisniewska statt Wiśniewska
Rekonstruierbar aus der Nachricht?ja, solange niemand normalisiertnein, nie
Im Ziel als Fehler erkennbar?ja, sofort — sieht kaputt ausnein — sieht aus wie ein Name
Wer meldet es?jeder, der draufschautniemand, oft jahrelang

Mojibake ist laut und heilbar. Zeichenverlust ist leise und endgültig.

Der Grund steht in der vorletzten Zeile: Das Ergebnis eines Verlusts ist ein gültiger, plausibler Wert. Keine Prüfung kann einem Namen ansehen, dass er einmal anders geschrieben war.

Drei Wege, auf denen ein Zeichen verschwindet — alle drei sind Voreinstellungen realer Konvertierungswerkzeuge:

  1. Transliteration (ś → s) — der gefährlichste Fall, weil das Ergebnis plausibel ist.
  2. Ersatzzeichen (ś → ?) — immerhin sichtbar.
  3. Abbruch oder Trunkierung — sichtbar, aber leicht als Längenproblem fehlgedeutet.

Der Zeichenvorrat ist ein Vertragsgegenstand

Die Zeile „Zeichensatz: ISO 8859-1” in einem Schnittstellenkonzept sagt mehr zu, als ihr Verfasser meist geprüft hat. Die Abdeckung lässt sich ausrechnen:

Zeichensatzä ö ü ßpolnisch ś ć ń ł ż ź ą ętürkisch ğ ı İ şé è à ç ñ
8859/1 (Latin-1)janeinneinja
8859/15 (Latin-9)janeinneinja
8859/2 (Latin-2)jajanur şnur é ç
8859/9 (Latin-5)janeinjaja

Es gibt keinen Ein-Byte-Zeichensatz, der den Namensvorrat eines mitteleuropäischen Krankenhauses abdeckt. Deutsch plus Polnisch geht nur mit Latin-2, Deutsch plus Türkisch nur mit Latin-5, beides zusammen mit keinem von beiden.

Wer 8859/1 vereinbart, vereinbart damit implizit, dass ein Teil der Patientennamen nicht übertragbar ist. Was mit diesen Namen geschieht, steht in den seltensten Konzepten — und die Voreinstellung der Strecke entscheidet es dann still.

MSH-18 — drei Eigenschaften, die selten mitgelesen werden

  • Optional, Default ASCII. Fehlt das Feld, gilt der 7-Bit-Vorrat (ISO IR6). Jede Nachricht mit Umlaut und leerem MSH-18 liegt damit außerhalb ihrer eigenen Deklaration — was in der Praxis niemanden stört und die Deklaration endgültig zur Formsache macht.
  • Wiederholbar (Sequenz 18, ID, optional, RP = Y). Zweite und folgende Vorkommen benennen zusätzliche Zeichensätze, zwischen denen die Nachricht per Escape-Sequenz umschaltet. HL7 v2 stammt aus einer Zeit, in der ein Zeichensatz nicht genügte und Unicode keine Selbstverständlichkeit war.
  • Tabelle 0211 listet Zeichensätze, keine Sprachen. Geläufig sind ASCII, 8859/1–8859/9, 8859/15, ostasiatische Sätze und — im heutigen Tabellenstand — UNICODE UTF-8 (UNICODE gilt als abgekündigt). Der Tabellenstand ist versionsabhängig; vor einer Zusage im versionsrichtigen Anhang nachschlagen.

Escape-Sequenzen haben zwei verschiedene Aufgaben

§ 2.7 definiert einen abgeschlossenen Satz; das Escape-Zeichen selbst steht in MSH-2 und ist nicht fest verdrahtet.

SequenzBedeutung
\F\ \S\ \T\ \R\ \E\field / component / subcomponent / repetition separator, escape character
\H\ \N\start highlighting, normal text
\Xdddd...\hexadecimal data
\Zdddd...\locally defined escape sequence
\Cxxyy\single-byte character set escape sequence
\Mxxyyzz\multi-byte character set escape sequence

„No escape sequence may contain a nested escape sequence.”

Aufgabe A — ein Strukturzeichen als Text transportieren. Eine Adresse „Hauptstr. 5 & 7” muss als Hauptstr. 5 \T\ 7 übertragen werden. Unterbleibt das, entsteht keine ungültige Nachricht, sondern eine wohlgeformte mit einer Subkomponente mehr. Kein Parser meldet etwas.

Aufgabe B — ein Zeichen transportieren, das der Zeichensatz nicht kennt. Dafür sind \Xdddd...\ (rohe Bytes in Hexpaaren) und die Umschaltsequenzen \Cxxyy\ / \Mxxyyzz\ gedacht, die auf ISO-IR-Repertoires zeigen (\C2842\ ASCII, \C2D41\ Latin Alphabet 1). Das ist der Grund, warum MSH-18 wiederholbar ist. In der Praxis unterstützt das kaum eine Installation; wer es einsetzt, verlagert das Problem in die Empfängerimplementierung. Der tragfähige Weg für Aufgabe B ist heute ein Zeichensatz, der den Vorrat abdeckt — also UTF-8.

Warum nichts davon auffällt

Prüfungprüftfindet einen Zeichenverlust?
Parser / SyntaxTrennzeichen, Segmentaufbaunein
Schema / Datentypist der Wert ein gültiges ST?nein
KonformitätsprofilOptionalität, Kardinalität, Wertevorrätenein — Namen haben keinen Wertevorrat
ACK-VertragAnnahme, Verarbeitungnein — AA, zu Recht
Fachliche PlausibilisierungBezug, Ordnung, Wertebereichenein — der Wert ist plausibel

Dazu eine Falle in der Beweisführung, die den Fall regelmäßig um Wochen verlängert:

Ein Protokolleintrag ist immer das Ergebnis des vorangegangenen Schritts und die Absicht des nächsten. Welches von beidem er ist, entscheidet die Frage, die man ihm stellt.

Ein Kommunikationsserver hält Nachrichten intern als Zeichenketten und protokolliert aus dieser Darstellung; serialisiert wird erst danach. Wer sein Protokoll fragt „was habe ich empfangen?”, bekommt eine wahre Antwort. Wer es fragt „was habe ich ausgeliefert?”, bekommt dieselbe Antwort — und sie ist falsch. Der Nachweis für diese Fehlerklasse führt deshalb über die Bytes beider Streckenabschnitte, für denselben Fall, an der Systemgrenze abgegriffen. Nicht über das Log der Quelle, nicht über das des Ziels, nicht über die Anzeige.

Ein Defekt, der zwischen zwei Nachrichten wohnt

Die übliche Frage „auf welcher Ebene sitzt der Defekt — Wert, Feld, Segment, Anordnung, Bezugsdokument?” hat hier kein Objekt:

  • Die beim Ziel eingehende Nachricht ist auf jeder Ebene einwandfrei: gültiger Wert, richtiges Feld, richtiges Segment, richtige Anordnung, Bezugsdokument eingehalten. Auch MSH-18 stimmt dort mit den Bytes überein — die Nachricht ist in sich vollkommen konsistent.
  • Die von der Quelle abgeschickte Nachricht ebenso.
  • Es sind zwei verschiedene Nachrichten; der Defekt existiert nur in ihrer Differenz.

Die Ebenenleiter verortet Aussagen. Was hier defekt ist, ist keine Aussage, sondern eine Handlung — die Serialisierung. Handlungen stehen auf keiner Sprosse.

Praktische Folge, und der Grund, warum solche Fälle im Ticketsystem im Kreis laufen: Jeder Beteiligte kann seine Unschuld an seiner Nachricht belegen — und hat damit recht.

Prüffrage, die die Ebene Wert von einem Vergleich trennt:

Wogegen wäre dieser Wert falsch? Gegen einen Wertevorrat, ein Format oder einen Typ → dann ist es die Sprosse Wert. Nur gegen einen anderen Wert in einer anderen Nachricht → dann ist es keine Sprosse, sondern ein Vergleich.

Einordnung: Kategorie 6, und warum

Nach dem Raster in Die sechs Fehlerkategorien ist der Zeichenverlust Kategorie 6 (unterhalb des Vertrags).

  • Bedingung 1 — Regelverstoß auf ungeprüfter Schicht: erfüllt. Die Zeichensatzschicht wird von keiner Prüfung des Zielsystems berührt, und eine Konvertierung, die Information vernichtet, ist von keiner Regel gedeckt — § 2.7 und die Wiederholbarkeit von MSH-18 stellen für genau diesen Fall Mechanismen bereit.
  • Bedingung 2 — die Information kommt nie an: erfüllt. Das Zeichen erreicht das Ziel in keiner Form; es ist vor dem Absenden vernichtet worden.

Der verbreitete Einwand gegen Bedingung 2 lautet: „Es kommt doch etwas an.” Er beruht auf einer Verwechslung:

Kategorie 6 ist keine Aussage über die Nachricht, sondern über eine Information. Eine Nachricht kann vollständig ankommen und trotzdem eine Information tragen, die nie abgeschickt wurde.

Abgrenzung gegen 4 (Mapping-Fehler) — die nächstliegende Alternative, weil eine Zeichensatzkonvertierung wörtlich eine Abbildung von A nach B ist und beide Endpunkte konform arbeiten:

Bei 4 ist die Information am Zielpunkt noch vorhanden, nur falsch abgebildet; bei 6 ist sie nicht mehr vorhanden. Operativer Test: Kann eine Korrektur allein beim Empfänger den Fall aus der vorliegenden Nachricht heilen? Ja → höchstens 4. Nein → 6.

Dieselbe Linie trennt auch die beiden Schäden dieser Seite: Mojibake ist im Ziel heilbar (4), Zeichenverlust nicht (6).

Abgrenzung gegen 5 (ungewollte Aussage): Bei 5 kommt die Aussage vollständig an und wird richtig verstanden — falsch ist ihr Inhalt. Bei 6 ist richtig, was ankommt, es ist nur nicht alles. Kurzform: Bei 5 ist die Aussage vollständig und falsch. Bei 6 ist sie richtig und unvollständig — und die Unvollständigkeit ist am Ziel nicht feststellbar.

Der zweite Befund. Wo ein Schnittstellenkonzept einen Zielzeichensatz vorgibt und zum Umgang mit nicht darstellbaren Zeichen schweigt, liegt daneben ein eigenständiger Befund der Kategorie 3: Die Vereinbarung sagt dazu nichts, also muss jemand auf der Strecke wählen. Er ist nicht die Ursache, sondern der Ermöglicher — und er ist der Grund, warum die Voreinstellung eines Produkts jahrelang eine Vertragslücke ausfüllen kann, ohne dass jemand sie unterschrieben hat.

Ein Kommunikationsserver ist kein Kabel. Er ist ein Verarbeitungsschritt mit eigener Konfiguration, eigenem Hersteller und eigenem Verantwortlichen — und er kommt in den meisten Schnittstellenkonzepten als Partei überhaupt nicht vor.

Daraus folgt der Adressat der Reparatur: weder Sender noch Empfänger, sondern die Strecke dazwischen und das Papier, das sie regelt.

Beispiel (synthetisch)

Nachname Wiśniewska, ein Streckenabschnitt in UTF-8, der folgende in ISO 8859-1:

Abschnitt 1, MSH-18 = UNICODE UTF-8
PID|1||100781^^^NS-A^MR||Wiśniewska^Anna^^^^^L||...
Bytes von PID-5.1.1:  57 69 C5 9B 6E 69 65 77 73 6B 61

Abschnitt 2, MSH-18 = 8859/1
PID|1||100781^^^NS-A^MR||Wisniewska^Anna^^^^^L||...
Bytes von PID-5.1.1:  57 69 73 6E 69 65 77 73 6B 61

In der zweiten Bytefolge steht kein defektes Byte, sondern ein 73 — der Buchstabe s. Aus Sicht jedes Empfängers ist das die Wahrheit über diesen Patienten.

Zum Kontrast derselbe Weg mit Müller:

UTF-8    :  4D C3 BC 6C 6C 65 72
Latin-1  :  4D FC 6C 6C 65 72      ← verlustfrei, denn ü existiert in Latin-1

Der Umlaut überlebt, das ś nicht. Ein Testset mit Müller und Groß prüft deshalb ausschließlich die Verfälschung und übersieht den Verlust vollständig.

Regel für Testdaten: Ein Testset muss mindestens ein Zeichen enthalten, das der vereinbarte Zeichensatz nicht kennt. Sonst ist diese Fehlerklasse im Test grundsätzlich unerreichbar.

Vier Änderungen und was sie wirklich tun

Der Fall taugt als Muster dafür, wie weit Reparatur, Sofortmaßnahme und Nachweis auseinanderliegen. Angenommen, ein Zielsystem zeigt transliterierte Namen:

ÄnderungWirkungKlasseSetzt sie an der Ursache an?
Zielsystem liest eingehende Bytes unabhängig von MSH-18 als UTF-8Symptom bleibt; die bisher funktionierenden Fälle brechen neu (FC ist kein gültiges UTF-8-Byte)wirkungslos und zusätzlich schädlich — richtige Schicht, falsche Stelle der Streckenein
Strecke lehnt nicht darstellbare Inhalte ab, statt zu ersetzenSymptom bleibt, aber der Fall scheitert sichtbar statt stillkeine Reparatur, sondern Umwandlung eines stillen Fehlers in einen lautennein — und trotzdem die richtige Sofortmaßnahme
Zeichensatz der Strecke und des Vertrags auf UTF-8Symptom verschwindet für neue Nachrichten; Bestand bleibtwirksamja — der Zeichenvorrat der Quelle wird gleichgültig
Strecke protokolliert die ausgehenden Bytes statt der internen Darstellungändert nichts am Defekt, macht ihn aber nachweisbarwirkungslos als Reparatur, wirksam als Nachweisnein, zielt auch nicht darauf

Operative Folge: Ablehnen sofort, Zeichensatz als Reparatur, Ausgangsprotokoll als Nachweis — und das Umstellen des Empfängers auf keinen Fall. Drei Dinge nacheinander, nicht drei Alternativen.

Und die Einschränkung, die jede Ersetzungsprobe an dieser Fehlerklasse hat:

Eine Ersetzungsprobe rechnet vorwärts. Ein bereits transliterierter Bestand ist aus dem Zielsystem heraus nicht rekonstruierbar, weil keine Nachricht, die es je erhalten hat, das Zeichen enthielt. Der einzige Weg zum Bestand führt zurück zur Quelle — Neuversand oder Abzug.


Transfer

Ein Zeichenverlust erzeugt keinen ungültigen Wert und keinen fehlenden Datensatz. Er erzeugt einen Bestand, dessen Namensvorrat systematisch ärmer ist als die Wirklichkeit — und zwar in genau die Richtung, die mit Herkunft korreliert. Wer Datensätze über Namen verknüpft, verliert überproportional dieselben Gruppen; wer auf solchen Beständen auswertet, misst eine Eigenschaft eines Zeichensatzes von 1987 und hält sie für einen Befund.

Nach dem Kahn-Rahmen ist der Defekt in keinem der beiden Bestände messbar. Der Quellbestand ist konform, vollständig und plausibel; der Zielbestand ebenso — ein transliterierter Name ist ein gültiger, vollständiger, plausibler Name. Weder Conformance noch Completeness noch Plausibility schlagen an, in keiner ihrer Ausprägungen. Das ist die schärfste Fassung der Rahmengrenze: Kahn misst Bestände, nicht Strecken — und hier gehen beide Seiten leer aus, weil der Defekt zwischen ihnen sitzt.

Messbar wird er trotzdem, und mit einer einzigen Zahl:

Zeichenvorrats-Histogramm der Quelle gegen das der Senke. Anteil der Datensätze mit mindestens einem Zeichen außerhalb des vereinbarten Zeichensatzes, beidseitig gezählt. Steht links 0,8 % und rechts 0,0 %, ist der Befund fertig — ohne dass ein Einzelfall angesehen wurde.

Das ist eine reine Validation-Messung im Sinne des Rahmens; keine Verification findet sie, weil auf beiden Seiten alles konform ist. Für jede Bestandsmigration — Systemwechsel, Zusammenlegung, Archivübernahme — kostet sie eine Stunde und ist der billigste Beweis, den man in einem solchen Projekt führen kann.

FHIR entschärft die Schicht: Die Serialisierungen sind UTF-8, es gibt kein Äquivalent zu MSH-18, über das man verhandeln könnte. Was bleibt, ist die Konvertierung an der Systemgrenze — und die Tatsache, dass FHIR den Schaden erbt, statt ihn zu erzeugen. Ein seit Jahren transliterierter Namensbestand erfüllt nach der Migration jede Konformitätsprüfung, jedes Must-Support und jede Kardinalität. Mit falschen Namen.

Fragen an die Kunden-IT

  • Welchen Zeichenvorrat müssen wir über diese Strecke tragen — welche Zeichen kommen in Ihren Patientenstammdaten tatsächlich vor? (Nicht die Deklaration erfragen, sondern den Vorrat. Die Antwort „nur deutsche Umlaute” ist am Bestand prüfbar und meistens falsch.)
  • Was tut die Strecke mit einem Zeichen, das im Zielzeichensatz nicht existiert: ersetzen, ablehnen, abbrechen? Wo ist das konfiguriert, und wer hat es entschieden?
  • Protokolliert der Kommunikationsserver seine interne Darstellung oder die ausgehenden Bytes?
  • Enthält das Testset ein Zeichen außerhalb des vereinbarten Zeichensatzes?
  • Wie viele Datensätze im Quellbestand tragen ein Zeichen außerhalb des vereinbarten Zeichensatzes — und wie viele im Zielbestand?

Prüffrage an die eigene Fragenliste, bevor sie rausgeht: Kann ich die Antwort selbst herstellen — durch Messen, Mitschneiden oder Nachlesen? Dann ist es keine Frage an die Gegenseite, sondern eine Aufgabe für mich.

Lektüre & Belege