UTF-8エンコーディングがどのように発明されたか:作成者の通信からの抜粋



誰もがUTF-8エンコーディングを知っています。UTF-8エンコーディングは長い間 インターネット空間を支配しており、長年使用されてきました。彼女についてはすべてが知られているように思われ、このトピックについて話すのは興味深いことではありません。ウィキペディアなどの人気のある資料を読んだ場合、英語版が「食堂のナプキンにスケッチされた」という奇妙な話を簡単に述べていることを除いて、実際には珍しいことは何もありません。 



実際、このエンコーディングの発明は、伝説的な人物であるケン・トンプソンがその作成に関与したという理由だけで、それほど平凡なものにはなり得ません。彼は、UNIXの作成者の1人であるDennis Ritchieと協力し、Cの開発に貢献し(その前身であるBを発明しました)、その後、Googleで働いている間、Go言語の作成に参加しました。 



あなたの前に-開発者がエンコーディングの作成の歴史を思い出すいくつかの文字の翻訳。 



キャラクター:



県entrisphere.com(で) - ケン・トンプソン





デニス・リッチーとケン・トンプソン(左)



- 「ロブ『司令官』パイク」 ロバート・パイク、ケン・トンプソンとUTF-8で働いていたカナダのプログラマー







acm.org(で)mkuhn - マルクスクーン、ドイツのコンピュータ科学者







ヘンリー(で)spsystems.net - ヘンリーSpurser、正規表現の実装の1つの著者







ラス・コックス< rsc@plan9.bell-labs.com > - ラスコックスプラン9に働いた、ベル研究所の従業員







GregerシステムLeijonhufvud < greger@friherr.com> -X / Open







Plan9スタッフの1人 -多言語を提供するためにUTF-8エンコーディングを最初に使用したオペレーティングシステム。







UTF-8-Unicode文字エンコード










2003年の通信





以下は、エンコーディングの作成者であるRobertとKenの間の通信であり、Robert Pikeは、UTF-8の作成への貢献が当然忘れられていると不満を述べています。ロバートは、彼の古い知人の1人に、メールサーバーのアーカイブを調べて、彼らの参加の証拠を見つけるように依頼します。(約あたり)



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
      
      







UTF-8の起源についての会話を見ると、同じ話が何度も繰り返されているのがわかります。 



間違ったバージョン: 



  1. UTF-8はIBMによって開発されました。
  2. Plan 9(ベル研究所が開発したオペレーティングシステム)で実装されました。


それは本当ではない。 1992年9月のある晩、ニュージャージーの食堂でUTF-8がナプキンでどのように発明されたかを直接見ました。 



それはこのように起こりました。オリジナルのISO10646 UTFを使用してPlan9の16ビット文字をサポートしましたが、これは嫌いでした。ある夜遅くに電話がかかってきたときにPlan9を出荷する準備ができていました。彼らはIBMから来たと思います。オースティンで開催されたX / Open委員会で彼らに会ったことを覚えています。彼らはケンと私に彼らのFSS / UTFプロジェクトを見てもらいたかった。 
(, ..) . Bell Labs , Plan 9 — , , , . , .



Unicode , , , , , .



(. .)
彼らがデザインを変更したいと思った理由を理解し、これは私たちの経験を利用して新しい標準を開発し、X / Openのスタッフにそれを宣伝してもらう良い機会であると判断しました。私たちは彼らにそれについて話さなければなりませんでした、そして彼らは私たちがそれを迅速に扱うという条件に同意しました。 



それから私たちは一口食べに行きました、そして夕食の間に、ケンはビートのパックを整理しました、そして私たちが戻ったとき、彼らはX /オープンからの人に電話して私たちの考えを彼らに説明しました。スケッチをメールで送ったところ、彼らは自分たちよりも優れていると答え(しかし、彼らは自分たちのバージョンを見せてくれなかったことを正確に覚えています)、いつ実装できるか尋ねました。
文字を区切るためのオプションの1つはスラッシュでしたが、これはファイルシステムを混乱させる可能性があり、エスケープシーケンスとして解釈する可能性があります。



(約あたり)
それは水曜日の夜に起こったように私には思えます。重要な会議が予定されている月曜日までにシステムを立ち上げることを約束しました。その夜、ケンはエンコーダー/デコーダーのコードを書き、私はCとグラフィックライブラリーを扱い始めました。翌日、コードの準備が整い、システムのテキストファイルの変換を開始しました。金曜日までに、プラン9はすでにいわゆるUTF-8で稼働していました。 



そして後で物語は少し書き直されました。



なぜ彼らのFSS / UTFを使用しなかったのですか? 



私が覚えている限り、その最初の電話で、エンコードの要件をDesiderataに歌いましたが、FSS / UTFには少なくとも1つのものがありませんでした。つまり、ストリームの途中から取得したバイトのストリームを、わずかな数で同期する機能です。同期のために可能な限り文字 (文字境界の定義については上記を参照)。



それらを歌ったDesiderat
.



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





どこにも解決策がなかったので、私たちは自由にそれをやりたいと思いました。

「ストーリーはIBMによって発明され、Plan 9で実装された」というのは、RFC 2279のドキュメントに端を発していると思います。UTF-8が定着したとき、私たちは誰にもストーリーを伝えなかったのでとても嬉しかったです。 



私たちの誰ももうベル研究所で働いていませんが、私たちの話を裏付けることができる電子メールのアーカイブがあると確信しています、そして私は誰かにそれを掘り下げるように頼むことができます。



したがって、すべての功績は、それを可能にし、エンコーディングをプッシュしたX / OpenとIBMの人たちにありますが、Kenがそれを開発し、歴史書に何が書かれていても、私は彼を助けました。 



-ロブ




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
      
      







私はラス・コックスにアーカイブを掘り下げるように頼んだ。彼のメッセージを添付します。これは私が以前に投稿した話を裏付けるものであることにあなたは同意すると思います。 X / Openに送信した電子メール(Kenがこのドキュメントを編集して配布したと思います)には、文字境界の検出に関する新しい「desideratum番号6」が含まれています。 



X / Openの元のソリューションが私たちにどのような影響を与えたかはわかりません。それらは異なりますが、共通の特徴があります。詳細に調べたのを覚えていません。それはかなり前のことです (最後の手紙で、X / Openはそれらの実装を示していなかったと彼は言っています。約レーン)。しかし、ケンがナプキンにスケッチを書いた方法をよく覚えており、それを保存しておけばよかったのにと思います。 



-ロブ




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
      
      





ユーザーの うしかい座ファイル /sys/src/libc/port/rune.c



、1992年9月4日に除算が多いために変更されました 。ダンプ内のバージョンの時刻は19:51:55です。翌日、コメントが追加されましたが、それ以外の点では、1996年11月14日、戻り値を使用する代わりに runelen



値を明示的にチェックすることで高速化される まで変更されませんでした 。最後の変更は、2001年5月26日に追加されたときでした (RuneはUnicode値を含む構造体です。Runelenとrunetocharは、このデータ型で機能する関数です。約Trans。)メールボックスから、行のグラッピングによって生成されたいくつかの文字がありました rune



runetochar



runenlen







utf。 



1つ目はutf.c



、コピーで wctomb



あり、 mbtowc



(文字変換関数。約Per。)フル6バイトUTF-8、32ビットエンコーディングを処理 するファイルに関する ものです。runes.



フロー制御ロジックを使用すると、かなり見苦しく見えます。このコードは最初のメールから来たと思います。 



/usr/ken/utf/xutf



、その非自己同期エンコーディング方式のソースと思われるもののコピーを見つけました。電子メールの最後にUTF-8スキーマが追加されています(「7つのタイプを定義します」で始まります byte



)。 



9月2日午後11時44分10秒の日付の以下の手紙のバージョンが最初です。何度か編集した後、9月8日の朝に2番目のバージョンが出ました。メールサーバーのログには、レターの2番目のバージョンがどのように送信され、しばらくするとKenに返されるかが示されます。



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
      
      





がんばろう。



メールアーカイブからのファイル



次は、Russ Coxが彼に添付したメールサーバーダンプからの通信を含むファイルで、Robertの履歴の調査要求に応えています。これが「初版」です。(約)



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

      
      





FSS-UTFを変更するための提案は次のとおりです。前回とほぼ同じです。著者に謝罪します。 



コードはある程度テストされており、かなり良好な状態になっているはずです。このエンコーディングを使用するようにPlan9コードを再設計し、ディストリビューションをリリースして、初期テスト用に大学のユーザーを選択します。 



ファイルシステムセーフユニバーサル文字セット変換形式(FSS-UTF)




ISO / IEC 10646(Unicode)が国際標準として確立され、このUniversal Coded Character Set(UCS)の普及が期待されているため、これまでASCIIに基づいていたオペレーティングシステムは、新しい標準でエンコードできます。 UCSには、歴史的に確立されたオペレーティングシステムとCでプログラミングするための環境で解決する必要のあるいくつかの問題があり 



ます(以下のテキストでは、「歴史的なオペレーティングシステム」について何度か言及しています。この形容詞を省略したか、「既存」などに置き換えました。約レーン)



最大の問題は、UCSで使用されるエンコード方式です。つまり、UCS標準と既存のプログラミング言語、オペレーティングシステム、およびユーティリティとの統合です。プログラミング言語とオペレーティングシステムの問題は業界全体で対処されていますが、オペレーティングシステムとユーティリティによるUCSの処理にはまだ直面しています。 



オペレーティングシステムでのUCSの処理に関連する問題の中で、主な問題はファイルシステム内のデータの表示です。基本的な概念は、投資が行われた既存のオペレーティングシステムをサポートすると同時に、UCSによって提供される多数の文字を利用することです。 



UCSを使用すると、単一の文字セットを使用して多言語テキストをエンコードできます。ただし、UCSとUTFはヌルバイト(一部の言語では行末。約Per。)および/またはASCII /のスラッシュを保護しないため 、コーディングはUnixと互換性がありません。次の提案は、Unix互換のUCS変換形式を提供するため、Unixシステムは単一のエンコーディング内で多言語テキストをサポートできます。



このエンコード変換形式は、UCSを完全にサポートするための中間ステップとしてファイルをエンコードすることを目的としています。ただし、ほぼすべてのUnis実装が同じUCSサポートの問題に直面しているため、この提案は、この段階で一般的なエンコーディングの互換性を提供することを目的としています。



目的/目的




仮定に基づいて、OSファイルシステムでのUCSの処理と保存に関するほとんどすべての問題がわかっている場合、オペレーティングシステムの構造に違反することなく機能するUCS変換形式を使用する必要があることがわかります。目標は、フォーマット変換プロセスを使用してファイルをエンコードできるようにすることです。



変換フォーマットの基準




以下は、UCS変換フォーマットを定義する際に従うべきガイドラインです。



  1. 既存のファイルシステムとの互換性。

    ファイル名の一部としてヌルバイトとスラッシュ文字を使用することは禁止されています。 
  2. .

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


FSS-UTF




提案されたUCS変換形式は、[0,0x7fffffff]



文字ごとに複数のバイトと1、2、3、4、5、および6バイトの長さを使用して範囲内のUCS値をエンコードし ます。複数のバイトでエンコードする場合はすべて、先頭のバイトが使用されるバイト数を決定し、各バイトに最上位ビットが設定されます。 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;
}
      
      





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





郵送したのですが、ブラックホールに入ったのでコピーが届きませんでした。このインターネットアドレスは昏睡状態にあったに違いありません。



改訂されたレターの2番目のバージョン



次に、手紙のコピーが添付されます。これは、上記のように説明されています。「いくつかの修正の後、9月8日の朝に2番目のバージョンが出ました。」繰り返し部分はスポイラーの下に隠されています。(約翻訳)



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





私はついに自分のコピーを手に入れました。



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





隠しテキスト

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;
}

      
      





7バイトタイプを定義します。



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

      
      





コーディングは次のようになります。



>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

      
      





いくつかの注意:



  1. 2バイトは2 ^ 11文字の累乗をエンコードできますが、使用されるのは2 ^ 11-2 ^ 7のみです。0〜7Fの範囲のコードは無効と見なされます。これは、実際のメリットがない「魔法の」定数をたくさん追加するよりも優れていると思います。この注意は、すべての長いシーケンスに適用されます。
  2. 4、5、および6バイトのシーケンスは、政治的な理由でのみ存在します。私はそれらを削除したいと思います。
  3. 6バイトのシーケンスは32ビットにまたがり、FSS-UTFの提案は31にしか及びません。
  4. すべてのシーケンスは、そうでないバイトに同期されます Tx.





***



この短い通信はすべてをその場所に置きました。その「伝説のナプキン」は生き残っていませんが、コミュニティが彼らのメリットを認識するのに十分なメールサーバーアーカイブからの抜粋がありました。ウィキペディアはケンとロバートの名前と食堂のナプキンについての面白い事実を追加しました、そしてインターネット上でこの物語はいくつかの文字とからのダンプの一部を含む単純なテキストの形で「現状のまま」回覧され議論されますメールサーバー。 



Plan 9オペレーティングシステムは長い間忘れられており、何のために書かれたのか、なぜ「ナンバーナイン」だったのかを誰も覚えていません。ほぼ30年後のUTF-8は依然として関連性があり、廃止されることはありません。



これは単なるエンコーディングのように見えますが、少し掘り下げてみると、このような単純な話でも面白いことがあります。技術開発の黎明期には、歴史の中で何が撃ち落とされ、何が忘れられるかを予測することは不可能でした。



アーカイブソース






All Articles