Wie die UTF-8-Codierung erfunden wurde: Auszüge aus der Korrespondenz der Autoren



Jeder kennt die UTF-8-Codierung, die seit langem den Internetraum dominiert und seit vielen Jahren verwendet wird. Es scheint, dass alles über sie bekannt ist, und zu diesem Thema gibt es nichts Interessantes zu erzählen. Wenn Sie populäre Ressourcen wie Wikipedia lesen, dann gibt es dort wirklich nichts Ungewöhnliches, außer dass die englische Version kurz eine seltsame Geschichte darüber erwähnt, wie sie "auf einer Serviette in einem Diner skizziert" wurde. 



Tatsächlich kann die Erfindung dieser Kodierung nicht so banal sein, schon allein deshalb, weil Ken Thompson, eine legendäre Person, an ihrer Entstehung beteiligt war. Er arbeitete mit Dennis Ritchie zusammen, war einer der Schöpfer von UNIX, trug zur Entwicklung von C bei (erfand seinen Vorgänger - B) und beteiligte sich später, während er bei Google arbeitete, an der Entwicklung der Go-Sprache. 



Vor Ihnen - die Übersetzung mehrerer Buchstaben, in denen sich die Entwickler an den Verlauf der Erstellung der Codierung erinnern. 



Zeichen:



ken (at) entrisphere.com - Ken Thompson





Ken Thompson (links) mit Dennis Ritchie



"Rob 'Commander' Pike" - Robert Pike , ein kanadischer Programmierer, der mit Ken Thompson







mkuhn (at) acm.org - Markus an UTF-8 arbeitete Kuhn , deutscher Informatiker







henry (at) spsystems.net - Henry Spurser , Autor einer der RegExp-Implementierungen







Russ Cox < rsc@plan9.bell-labs.com > - Russ Cox , Mitarbeiter von Bell Labs, der am Plan 9







Greger gearbeitet hat System Leijonhufvud < greger@friherr.com> - Einer der Mitarbeiter von X / Open







Plan 9 - Das Betriebssystem, das als erstes die UTF-8-Codierung verwendet hat, um Mehrsprachigkeit zu gewährleisten.







UTF-8 - Unicode-Zeichencodierung










Korrespondenz 2003





Nachfolgend finden Sie die Korrespondenz zwischen den Erstellern der Codierung, Robert und Ken, die Robert Pike begann und sich darüber beklagte, dass ihr Beitrag zur Erstellung von UTF-8 zu Unrecht vergessen wurde. Robert bittet einen seiner alten Bekannten, in den Archiven des Mailservers zu stöbern und dort Beweise für ihre Teilnahme zu finden. (ca. per.)



Subject: UTF-8 history
From: "Rob 'Commander' Pike" <r (at) google.com>
Date: Wed, 30 Apr 2003 22:32:32 -0700 (Thu 06:32 BST)
To: mkuhn (at) acm.org, henry (at) spsystems.net
Cc: ken (at) entrisphere.com
      
      







Wenn ich mir die Gespräche über die Ursprünge von UTF-8 ansehe, sehe ich, dass dieselbe Geschichte immer wieder wiederholt wird. 



Falsche Version: 



  1. UTF-8 wurde von IBM entwickelt.
  2. Es wurde in Plan 9 (einem von Bell Laboratories entwickelten Betriebssystem) implementiert.


Es ist nicht wahr. Ich habe aus erster Hand gesehen, wie UTF-8 eines Abends im September 1992 in einem Diner in New Jersey auf einer Serviette erfunden wurde. 



Es ist auf diese Weise passiert. Wir haben die ursprüngliche UTF nach ISO 10646 verwendet, um 16-Bit-Zeichen in Plan 9 zu unterstützen, die wir hassten, und waren bereit, Plan 9 zu versenden, als mich einige Leute eines Nachts spät anriefen. Ich glaube, sie waren von IBM. Ich erinnere mich, sie auf der Sitzung des X / Open-Komitees in Austin getroffen zu haben. Sie wollten, dass Ken und ich ihr FSS / UTF-Projekt sehen. 
(, ..) . Bell Labs , Plan 9 — , , , . , .



Unicode , , , , , .



(. .)
Wir haben verstanden, warum sie das Design ändern wollten, und entschieden, dass dies eine gute Gelegenheit ist, unsere Erfahrung zu nutzen, um einen neuen Standard zu entwickeln und die Jungs von X / Open dazu zu bringen, ihn zu promoten. Wir mussten ihnen davon erzählen und sie waren sich einig, dass wir uns schnell darum kümmern. 



Dann gingen wir essen, und während des Abendessens sortierte Ken die Beats aus, und als wir zurückkamen, riefen sie die Jungs von X / Open an und erklärten ihnen unsere Idee. Wir haben unsere Skizze per Post verschickt und sie haben geantwortet, dass sie besser ist als ihre (aber ich erinnere mich genau, dass sie uns ihre Version nicht gezeigt haben) und gefragt, wann wir sie implementieren können.
Eine der Optionen zum Abgrenzen von Zeichen war ein Schrägstrich, der jedoch das Dateisystem verwirren und als Escape-Sequenz interpretieren könnte.



(ca. per.)
Es scheint mir, dass es am Mittwochabend passiert ist. Wir haben versprochen, das System bis Montag zu starten, wenn meiner Meinung nach ein wichtiges Treffen geplant ist. An diesem Abend schrieb Ken den Encoder / Decoder-Code und ich begann mich mit C und den Grafikbibliotheken zu beschäftigen. Am nächsten Tag war der Code fertig und wir begannen mit der Konvertierung der Textdateien des Systems. Bis Freitag war Plan 9 bereits auf dem sogenannten UTF-8 in Betrieb. 



Und später wurde die Geschichte ein wenig umgeschrieben.



Warum haben wir nicht einfach ihre FSS / UTF verwendet? 



Soweit ich mich erinnere, habe ich bei diesem ersten Telefonanruf Desiderata meine Anforderungen für die Codierung mitgeteilt, und FSS / UTF hatte nicht mindestens eines - die Fähigkeit, einen aus der Mitte des Streams entnommenen Bytestrom mit möglichst wenigen zu synchronisieren Zeichen wie möglich für die Synchronisation (siehe oben zum Definieren von Zeichengrenzen.



sang ihnen Desiderat
.



, 1971 , : «Desiderata» , , : «». , « » « ». ( .)





Da es nirgendwo eine Lösung gab, konnten wir dies tun, wie wir wollten.

Ich denke, "die Geschichte wurde von IBM erfunden und in Plan 9 implementiert" hat ihren Ursprung in der RFC 2279-Dokumentation. Wir waren so glücklich, als UTF-8 Wurzeln schlug, dass wir die Geschichte niemandem erzählten. 



Keiner von uns arbeitet mehr bei Bell Labs, aber ich bin sicher, dass es ein E-Mail-Archiv gibt, das unsere Geschichte bestätigen kann, und ich kann jemanden bitten, sich damit zu beschäftigen.



Der gesamte Verdienst geht an die Mitarbeiter von X / Open und IBM, die es möglich gemacht und die Codierung vorangetrieben haben, aber Ken hat sie entwickelt, und ich habe ihm dabei geholfen, egal was in den Geschichtsbüchern steht. 



-Rauben




Date: Sat, 07 Jun 2003 18:44:05 -0700
From: "Rob `Commander' Pike" <r@google.com>
To: Markus Kuhn <Markus.Kuhn@cl.cam.ac.uk>
cc: henry@spsystems.net, ken@entrisphere.com,
Greger Leijonhufvud <greger@friherr.com>
Subject: Re: UTF-8 history
      
      







Ich bat Russ Cox, in den Archiven zu graben. Ich hänge seine Nachricht an. Ich denke, Sie werden mir zustimmen, dass dies die Geschichte bestätigt, die ich zuvor gepostet habe. Die E-Mail, die wir an X / Open gesendet haben (ich glaube, Ken hat dieses Dokument bearbeitet und verteilt), enthält ein neues "Desiderat Nummer 6" zur Erkennung von Zeichengrenzen. 



Wir werden nicht mehr wissen, welche Auswirkungen die ursprüngliche Lösung von X / Open auf uns hatte. Obwohl sie unterschiedlich sind, haben sie gemeinsame Eigenschaften. Ich kann mich nicht erinnern, es im Detail betrachtet zu haben, es ist zu lange her (im letzten Brief sagt er, dass X / Open ihnen ihre Implementierung nicht gezeigt hat. Ca. Lane) . Aber ich erinnere mich sehr gut, wie Ken Skizzen auf eine Serviette schrieb und sich dann wünschte, wir hätten sie gespeichert. 



-Rauben




From: Russ Cox <rsc@plan9.bell-labs.com>
To: r@google.com
Subject: utf digging
Date-Sent: Saturday, June 07, 2003 7:46 PM -0400
      
      





Die Benutzer- Boot-Datei /sys/src/libc/port/rune.c



wurde am 4. September 1992 von Division-Heavy geändert . Die Version im Dump hat eine Zeit von 19:51:55. Am nächsten Tag wurde ein Kommentar hinzugefügt, der sich jedoch erst am 14. November 1996 änderte, als er runelen



beschleunigt wurde, indem der Wert explizit überprüft wurde, rune



anstatt den Rückgabewert zu verwenden runetochar



. Die letzte Änderung erfolgte am 26. Mai 2001, als sie hinzugefügt wurde runenlen



. (Rune ist eine Struktur, die einen Unicode-Wert enthält. Runelen und Runetochar sind Funktionen, die mit diesem Datentyp arbeiten. Ca. Trans.)



Es gab mehrere Buchstaben aus Ihren Postfächern, die durch Zeilenumbruch generiert wurden utf. 



Die erste handelt von einer Datei utf.c



, die eine Kopie ist wctomb



und mbtowc



(Zeichenkonvertierungsfunktionen. Ca. Per.) Die vollständige 6-Byte-UTF-8-32-Bit-Codierung verarbeitet. runes.



Mit der Flusssteuerungslogik sieht sie ziemlich hässlich aus. Ich denke, dieser Code stammt aus dieser ersten E-Mail. 



In /usr/ken/utf/xutf



fand ich eine Kopie der Quelle dieser nicht selbstsynchronisierenden Codierungsmethode, wobei das UTF-8-Schema an das Ende der E-Mail angehängt wurde (beginnt mit "Wir definieren 7 Typen byte



"). 



Die unten stehende Version des Briefes vom 2. September, 23:44:10 Uhr ist die erste. Nach mehreren Änderungen erschien am Morgen des 8. September die zweite Version. Die Mailserver-Protokolle zeigen, wie die zweite Version des Briefes gesendet wird, und kehren nach einer Weile zu Ken zurück:



helix: Sep  8 03:22:13: ken: upas/sendmail: remote inet!xopen.co.uk!xojig
>From ken Tue Sep  8 03:22:07 EDT 1992 (xojig@xopen.co.uk) 6833
helix: Sep  8 03:22:13: ken: upas/sendmail: delivered rob From ken Tue Sep 8 03:22:07 EDT 1992 6833
helix: Sep  8 03:22:16: ken: upas/sendmail: remote pyxis!andrew From ken Tue Sep  8 03:22:07 EDT 1992 (andrew) 6833
helix: Sep  8 03:22:19: ken: upas/sendmail: remote coma!dmr From ken Tue Sep  8 03:22:07 EDT 1992 (dmr) 6833
helix: Sep  8 03:25:52: ken: upas/sendmail: delivered rob From ken Tue Sep 8 03:24:58 EDT 1992 141
helix: Sep  8 03:36:13: ken: upas/sendmail: delivered ken From ken Tue Sep 8 03:36:12 EDT 1992 6833
      
      





Alles Gute.



Dateien aus dem Mail-Archiv



Als nächstes folgt eine Datei mit der Korrespondenz aus dem Mailserver-Dump, die Russ Cox als Antwort auf Roberts Aufforderung, sich mit der Geschichte zu befassen, an seinen angehängt hat. Dies ist die "erste Version". (ca.)



>From ken Fri Sep  4 03:37:39 EDT 1992

      
      





Hier ist unser Vorschlag zum Ändern von FSS-UTF. Es ist ungefähr das Gleiche wie im vorherigen. Ich entschuldige mich beim Autor. 



Der Code wurde bis zu einem gewissen Grad getestet und sollte in einem ziemlich guten Zustand sein. Wir haben den Plan 9-Code neu gestaltet, um diese Codierung zu verwenden. Wir werden die Distribution freigeben und Universitätsbenutzer für erste Tests auswählen. 



Dateisystemsicheres universelles Zeichensatz-Transformationsformat (FSS-UTF)




Da ISO / IEC 10646 (Unicode) als internationaler Standard etabliert ist und eine breite Akzeptanz dieses universellen codierten Zeichensatzes (UCS) erwartet wird, müssen Betriebssysteme, die historisch auf ASCII basieren, Wege entwickeln, um eine große Anzahl von Zeichen darzustellen und zu handhaben kann mit dem neuen Standard codieren. UCS hat mehrere Probleme, die in historisch etablierten Betriebssystemen und der Umgebung für die Programmierung in C gelöst werden müssen. 



(Der folgende Text erwähnt mehrmals "historische Betriebssysteme". Anscheinend im Zusammenhang mit "historisch mit ASCII-Codierung arbeiten" dieses Epitheton weggelassen oder durch "existierende" usw. ersetzt.



Das größte Problem ist das in UCS verwendete Codierungsschema. Die Integration des UCS-Standards in bestehende Programmiersprachen, Betriebssysteme und Dienstprogramme. Probleme in Programmiersprachen und Betriebssystemen werden branchenübergreifend angegangen, aber wir sind immer noch mit dem Umgang mit BKS durch Betriebssysteme und Dienstprogramme konfrontiert. 



Unter den Problemen, die mit dem Umgang mit BKS in Betriebssystemen verbunden sind, ist das Hauptproblem die Darstellung von Daten innerhalb des Dateisystems. Das zugrunde liegende Konzept besteht darin, die vorhandenen Betriebssysteme zu unterstützen, in die die Investition getätigt wurde, und gleichzeitig die große Anzahl von Zeichen zu nutzen, die von UCS bereitgestellt werden. 



UCS ermöglicht die Codierung von mehrsprachigem Text mit einem einzigen Zeichensatz. UCS und UTF schützen jedoch keine Null-Bytes (das Zeilenende in einigen Sprachen. Ca. Per.) Und / oder einen Schrägstrich in ASCII /, wodurch die Codierung mit Unix nicht kompatibel wird. Der folgende Vorschlag bietet ein Unix-kompatibles UCS-Transformationsformat, sodass Unix-Systeme mehrsprachigen Text in einer einzigen Codierung unterstützen können.



Dieses Codierungskonvertierungsformat dient zum Codieren von Dateien als Zwischenschritt zur vollständigen UCS-Unterstützung. Da jedoch fast alle Unis-Implementierungen mit denselben UCS-Unterstützungsproblemen konfrontiert sind, soll dieser Vorschlag zu diesem Zeitpunkt eine allgemeine Codierungskompatibilität bieten.



Zweck / Ziel




Basierend auf der Annahme erhalten wir, dass wir, wenn fast alle Probleme beim Verarbeiten und Speichern von UCS in Betriebssystem-Dateisystemen bekannt sind, ein solches UCS-Konvertierungsformat verwenden müssen, das funktioniert, ohne die Struktur des Betriebssystems zu verletzen. Das Ziel ist, dass der Formatkonvertierungsprozess zum Codieren der Datei verwendet werden kann.



Kriterien für das Konvertierungsformat




Die folgenden Richtlinien müssen beim Definieren des UCS-Konvertierungsformats beachtet werden:



  1. Kompatibilität mit vorhandenen Dateisystemen.

    Es ist verboten, ein Null-Byte und einen Schrägstrich als Teil des Dateinamens zu verwenden. 
  2. .

    ASCII. UCS, ASCII, ASCII.
  3. UCS .
  4. .
  5. , , .
  6. , (. ..).


FSS-UTF




Das vorgeschlagene UCS-Transformationsformat codiert UCS-Werte in einem Bereich unter [0,0x7fffffff]



Verwendung mehrerer Bytes pro Zeichen und Längen von 1, 2, 3, 4, 5 und 6 Bytes. In allen Fällen der Codierung mit mehr als einem Byte bestimmt das führende Byte die Anzahl der verwendeten Bytes, wobei in jedem Byte das höchstwertige Bit gesetzt ist. Jedes Byte, das nicht mit 10XXXXXX beginnt, ist der Beginn einer UCS-Zeichenfolge.



Eine einfache Möglichkeit, sich an das Format zu erinnern: Die Anzahl der hohen Bytes im ersten Byte bedeutet die Anzahl der Bytes in einem Multibyte-Zeichen.



Bits    Hex Min  Hex Max  Byte Sequence in Binary
1    7  00000000 0000007f 0vvvvvvv
2   11  00000080 000007FF 110vvvvv 10vvvvvv
3   16  00000800 0000FFFF 1110vvvv 10vvvvvv 10vvvvvv
4   21  00010000 001FFFFF 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv
5   26  00200000 03FFFFFF 111110vv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv
6   31  04000000 7FFFFFFF 1111110v 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv

      
      





Der Multibyte-codierte UCD-Zeichenwert ist eine Verkettung von V-Bits. Wenn mehrere Codierungsmethoden möglich sind, z. B. UCS 0, wird die kürzeste als akzeptabel angesehen.



Im Folgenden sind Beispiele für Implementierungen von Standard - C - Funktionen wcstombs()



und mbstowcs()



die zeigen Algorithmen für von UCS zu Konvertierungsformat konvertieren und von Konvertierungsformat zu UCS konvertieren. Beispiele für Implementierungen sind Fehlerprüfungen, von denen einige aus Gründen der Konsistenz möglicherweise nicht erforderlich sind:



typedef

struct
{
    int   cmask;
    int   cval;
    int   shift;
    long  lmask;
    long  lval;
} Tab;

static
Tab       tab[] =
{
    0x80, 0x000*6,   0x7F,         0,            /* 1 byte sequence */
    0xE0, 0xC01*6,   0x7FF,        0x80,         /* 2 byte sequence */
    0xF0, 0xE02*6,   0xFFFF,              0x800,        /* 3 byte sequence */
    0xF8, 0xF03*6,   0x1FFFFF,     0x10000,      /* 4 byte sequence */
    0xFC, 0xF84*6,   0x3FFFFFF,    0x200000,     /* 5 byte sequence */
    0xFE, 0xFC5*6,   0x7FFFFFFF,   0x4000000,    /* 6 byte sequence */
    0,                                              /* end of table */
};

int
mbtowc(wchar_t *p, char *s, size_t n)
{
    long l;
    int c0, c, nc;
    Tab *t;

    if(s == 0)
        return 0;

    nc = 0;
    if(n <= nc)
        return -1;
    c0 = *s & 0xff;
    l = c0;
    for(t=tab; t->cmask; t++) {
        nc++;
        if((c0 & t->cmask) == t->cval) {
            l &= t->lmask;
            if(l < t->lval)
                return -1;
            *p = l;
            return nc;
        }
        if(n <= nc)
            return -1;
        s++;
        c = (*s ^ 0x80) & 0xFF;
        if(c & 0xC0)
            return -1;
        l = (l<<6) | c;
    }
    return -1;
}

int
wctomb(char *s, wchar_t wc)
{
    long l;
    int c, nc;
    Tab *t;

    if(s == 0)
        return 0;

    l = wc;
    nc = 0;
    for(t=tab; t->cmask; t++) {
        nc++;
        if(l <= t->lmask) {
            c = t->shift;
            *s = t->cval | (l>>c);
            while(c > 0) {
                c -= 6;
                s++;
                *s = 0x80 | ((l>>c) & 0x3F);
            }
            return nc;
        }
    }
    return -1;
}
      
      





>From ken Tue Sep  8 03:24:58 EDT 1992
      
      





Ich schickte es per Post, aber der Brief ging in ein schwarzes Loch, so dass ich meine Kopie nicht erhielt. Diese Internetadresse muss im Koma liegen.



Zweite Version des Briefes mit Überarbeitungen



Dann wird eine Kopie des Briefes angehängt, die oben wie folgt beschrieben wurde: "Nach mehreren Korrekturen kam am Morgen des 8. September die zweite Version heraus." Der sich wiederholende Teil ist unter dem Spoiler versteckt. (ca. übersetzt)



>From ken Tue Sep  8 03:42:43 EDT 1992
      
      





Ich habe endlich mein Exemplar bekommen.



--- /usr/ken/utf/xutf from dump of Sep 2 1992 ---
      
      





Versteckter Text

File System Safe Universal Character Set Transformation Format (FSS-UTF)




ISO/IEC 10646 (Unicode) (UCS), , ASCII, , . UCS , C. 



, UCS. UCS , . , UCS . 



, UCS , . , , , , UCS. 



UCS . UCS UTF ( . . .) / ASCII /, Unix. UCS, Unix, , , Unix- .



, UCS. , Unis UCS, .



/




, UCS ,   UCS, . , .






  , , UCS:



  1. .

  2. .

    ASCII. UCS, ASCII, ASCII.
  3. UCS .
  4. .
  5. , , .
  6. , (. ..).


FSS-UTF




UCS UCS [0,0x7fffffff]



1, 2, 3, 4, 5, 6 . , . , 10XXXXXX, UCS.



: .



Bits    Hex Min  Hex Max  Byte Sequence in Binary
1    7  00000000 0000007f 0vvvvvvv
2   11  00000080 000007FF 110vvvvv 10vvvvvv
3   16  00000800 0000FFFF 1110vvvv 10vvvvvv 10vvvvvv
4   21  00010000 001FFFFF 11110vvv 10vvvvvv 10vvvvvv 10vvvvvv
5   26  00200000 03FFFFFF 111110vv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv
6   31  04000000 7FFFFFFF 1111110v 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv 10vvvvvv

      
      





UCD — v-. , UCS 0, .



C wcstombs()



mbstowcs()



, UCS UCS. , :



typedef

struct
{
    int   cmask;
    int   cval;
    int   shift;
    long  lmask;
    long  lval;
} Tab;

static
Tab       tab[] =
{
    0x80, 0x000*6,   0x7F,         0,            /* 1 byte sequence */
    0xE0, 0xC01*6,   0x7FF,        0x80,         /* 2 byte sequence */
    0xF0, 0xE02*6,   0xFFFF,              0x800,        /* 3 byte sequence */
    0xF8, 0xF03*6,   0x1FFFFF,     0x10000,      /* 4 byte sequence */
    0xFC, 0xF84*6,   0x3FFFFFF,    0x200000,     /* 5 byte sequence */
    0xFE, 0xFC5*6,   0x7FFFFFFF,   0x4000000,    /* 6 byte sequence */
    0,                                              /* end of table */
};

int
mbtowc(wchar_t *p, char *s, size_t n)
{
    long l;
    int c0, c, nc;
    Tab *t;

    if(s == 0)
        return 0;

    nc = 0;
    if(n <= nc)
        return -1;
    c0 = *s & 0xff;
    l = c0;
    for(t=tab; t->cmask; t++) {
        nc++;
        if((c0 & t->cmask) == t->cval) {
            l &= t->lmask;
            if(l < t->lval)
                return -1;
            *p = l;
            return nc;
        }
        if(n <= nc)
            return -1;
        s++;
        c = (*s ^ 0x80) & 0xFF;
        if(c & 0xC0)
            return -1;
        l = (l<<6) | c;
    }
    return -1;
}

int
wctomb(char *s, wchar_t wc)
{
    long l;
    int c, nc;
    Tab *t;

    if(s == 0)
        return 0;

    l = wc;
    nc = 0;
    for(t=tab; t->cmask; t++) {
        nc++;
        if(l <= t->lmask) {
            c = t->shift;
            *s = t->cval | (l>>c);
            while(c > 0) {
                c -= 6;
                s++;
                *s = 0x80 | ((l>>c) & 0x3F);
            }
            return nc;
        }
    }
    return -1;
}
      
      





int mbtowc(wchar_t *p, const char *s, size_t n)
{
       unsigned char *uc;      /* so that all bytes are nonnegative */

       if ((uc = (unsigned char *)s) == 0)
           return 0;               /* no shift states */
       if (n == 0)
           return -1;
       if ((*p = uc[0]) < 0x80)
           return uc[0] != '\0';   /* return 0 for '\0', else 1 */
       if (uc[0] < 0xc0)
       {
           if (n < 2)
               return -1;
           if (uc[1] < 0x80)
               goto bad;
           *p &= 0x3f;
           *p <<= 7;
           *p |= uc[1] & 0x7f;
           *p += OFF1;
           return 2;
       }
       if (uc[0] < 0xe0)
       {
           if (n < 3)
               return -1;
           if (uc[1] < 0x80 || uc[2] < 0x80)
               goto bad;
           *p &= 0x1f;
           *p <<= 14;
           *p |= (uc[1] & 0x7f) << 7;
           *p |= uc[2] & 0x7f;
           *p += OFF2;
           return 3;
       }
       if (uc[0] < 0xf0)
       {
           if (n < 4)
               return -1;
           if (uc[1] < 0x80 || uc[2] < 0x80 || uc[3] < 0x80)
               goto bad;
           *p &= 0x0f;
           *p <<= 21;
           *p |= (uc[1] & 0x7f) << 14;
           *p |= (uc[2] & 0x7f) << 7;
           *p |= uc[3] & 0x7f;
           *p += OFF3;
           return 4;
       }
       if (uc[0] < 0xf8)
       {
           if (n < 5)
               return -1;
           if (uc[1] < 0x80 || uc[2] < 0x80 || uc[3] < 0x80 || uc[4] < 0x80)
               goto bad;
           *p &= 0x07;
           *p <<= 28;
           *p |= (uc[1] & 0x7f) << 21;
           *p |= (uc[2] & 0x7f) << 14;
           *p |= (uc[3] & 0x7f) << 7;
           *p |= uc[4] & 0x7f;
           if (((*p += OFF4) & ~(wchar_t)0x7fffffff) == 0)
               return 5;
       }
bad:;
       errno = EILSEQ;
       return -1;
}

      
      





Wir definieren 7 Bytetypen:



T0 0xxxxxxx      7 free bits
Tx 10xxxxxx      6 free bits
T1 110xxxxx      5 free bits
T2 1110xxxx      4 free bits
T3 11110xxx      3 free bits
T4 111110xx      2 free bits
T5 111111xx      2 free bits

      
      





Die Codierung sieht folgendermaßen aus:



>From hex Thru hex      Sequence             Bits
00000000  0000007f      T0                   7
00000080  000007FF      T1 Tx                11
00000800  0000FFFF      T2 Tx Tx             16
00010000  001FFFFF      T3 Tx Tx Tx          21
00200000  03FFFFFF      T4 Tx Tx Tx Tx       26
04000000  FFFFFFFF      T5 Tx Tx Tx Tx Tx    32

      
      





Einige Notizen:



  1. Zwei Bytes können eine Potenz von 2 ^ 11 Zeichen codieren, es werden jedoch nur 2 ^ 11-2 ^ 7 verwendet. Codes im Bereich von 0 bis 7F werden als ungültig betrachtet. Ich denke, das ist besser als das Hinzufügen einer Reihe von "magischen" Konstanten ohne wirklichen Nutzen. Diese Bemerkung gilt für alle längeren Sequenzen.
  2. Sequenzen von 4, 5 und 6 Bytes existieren nur aus politischen Gründen. Ich würde sie lieber entfernen.
  3. Die 6-Byte-Sequenz umfasst 32 Bit, der FSS-UTF-Vorschlag umfasst nur 31 Bit.
  4. Alle Sequenzen werden mit jedem anderen Byte synchronisiert Tx.





***.



Diese kurze Korrespondenz setzte alles an seinen Platz. Obwohl diese „legendäre Serviette“ nicht überlebt hat, gab es genügend Auszüge aus dem Mailserver-Archiv, damit die Community ihre Vorzüge erkennen konnte. Wikipedia fügte die Namen von Ken und Robert und eine lustige Tatsache über eine Serviette in einem Diner hinzu, und im Internet wird diese Geschichte "wie sie ist" in Form eines einfachen Textes verbreitet und diskutiert, der mehrere Buchstaben und einen Teil eines Dumps aus dem Diner enthält Mail-Server. 



Das Plan 9-Betriebssystem ist längst vergessen, niemand erinnert sich daran, wofür es geschrieben wurde und warum es „Nummer neun“ war, und UTF-8, fast dreißig Jahre später, ist immer noch relevant und wird nicht in den Ruhestand gehen.



Es scheint, dass dies nur eine Kodierung ist, aber selbst eine so einfache Geschichte kann unterhaltsam sein, wenn Sie sich ein wenig damit beschäftigen. Zu Beginn der Technologieentwicklung war es unmöglich vorherzusagen, was in der Geschichte schießen und untergehen würde und was vergessen würde.



Archivquelle






All Articles