UTF-8

UTF-8(ユーティーエフはち)は、Unicodeで定義された全てのコードポイントをエンコード可能な文字符号化方式。 1つのコードポイントは1 - 4バイトにエンコードされる。

U+0000 - U+007Fまでは、ASCIIとの互換性があり、マルチバイト文字とシングルバイトの領域が互いに重ならないため、マルチバイト文字を考慮せずに作られたプログラム(strchr, strtokなど)を、そのまま使用することができる。

かつては非最短形式を許す実装があり、セキュリティ上の問題が生じたこともあるため、現在は非最短形式はすべてエラーとすると定義されている。

UTF-8 → CodePoint

// エラーチェックは省略
int c = -1;
if ((p[0] & 0x80) == 0) {
    c = a & 0x7F;
} else if ((p[0] & 0xE0) == 0xC0) {
    c = ((p[0] & 0x1F) << 6) | (p[1] & 0x3F);
} else if ((p[0] & 0xF0) == 0xE0) {
    c = ((p[0] & 0x0F) << 12) | ((p[1] & 0x3F) << 6) | (p[2] & 0x3F);
} else if ((p[0] & 0xF8) == 0xF0) {
    c = ((p[0] & 0x07) << 18) | ((p[1] & 0x3F) << 12)  | ((p[2] & 0x3F) << 6) | (p[3] & 0x3F);
}

CodePoint → UTF-8

if (c < 0x7F) {
    *dst++ = c;
} else if (c < 0x7FF) {
    *dst++ = 0xC0 | (c >> 6);
    *dst++ = 0x80 | (c & 0x3F);
} else if (c < 0x10000) {
    *dst++ = 0xE0 | (c >> 12);
    *dst++ = 0x80 | ((c >> 6) & 0x3F);
    *dst++ = 0x80 | (c & 0x3F);
} else {
    *dst++ = 0xF0 | (c >> 18);
    *dst++ = 0x80 | ((c >> 12) & 0x3F);
    *dst++ = 0x80 | ((c >> 6) & 0x3F);
    *dst++ = 0x80 | (c & 0x3F);
}