UTF-8

UTF-8(ユーティーエフはち)は、Unicode文字列に適用できる文字符号化方式です。

1つのスカラー値は1 - 4バイトにエンコードされます。

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

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

UTF-8 → Scalar Value

// エラーチェックは省略
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);
}

Scalar Value → 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);
}