UTF-8 & Unicode, lo que con 0xC0 y 0x80?

He estado leyendo acerca de Unicode y UTF-8 en el último par de días y me vienen a menudo a través de una comparación bit a bit similar a este :

int strlen_utf8(char *s) 
{
  int i = 0, j = 0;
  while (s[i]) 
  {
    if ((s[i] & 0xc0) != 0x80) j++;
    i++;
  }
  return j;
}

Alguien puede aclarar la comparación con 0xc0 y la comprobación de si el bit más significativo ?

Gracias!

EDICIÓN: ANDed, no de comparación, se utiliza la palabra equivocada 😉

InformationsquelleAutor vdsf | 2010-10-12

1 Kommentar

  1. 86

    No es una comparación con 0xc0, es una operación lógica and con 0xc0.

    La máscara de bits 0xc0 es 11 00 00 00 por lo tanto, Y que está haciendo es extraer sólo la parte superior de dos bits:

        ab cd ef gh
    AND 11 00 00 00
        -- -- -- --
      = ab 00 00 00
    

    Esto se compara con 0x80 (binario 10 00 00 00). En otras palabras, la if declaración es la comprobación para ver si los dos primeros bits del valor no son iguales a 10.

    «¿Por qué?» Te oigo preguntar. Bueno, esa es una buena pregunta. La respuesta es que, en UTF-8, todos los bytes que comienzan con el patrón de bits 10 son los siguientes bytes de un multi-byte de la secuencia:

                        UTF-8
    Range              Encoding  Binary value
    -----------------  --------  --------------------------
    U+000000-U+00007f  0xxxxxxx  0xxxxxxx
    
    U+000080-U+0007ff  110yyyxx  00000yyy xxxxxxxx
                       10xxxxxx
    
    U+000800-U+00ffff  1110yyyy  yyyyyyyy xxxxxxxx
                       10yyyyxx
                       10xxxxxx
    
    U+010000-U+10ffff  11110zzz  000zzzzz yyyyyyyy xxxxxxxx
                       10zzyyyy
                       10yyyyxx
                       10xxxxxx
    

    Así, lo que este pequeño fragmento está haciendo es pasando a través de cada byte de la cadena UTF-8 y el recuento de todos los bytes que no son continuación de bytes (es decir, conseguir que la longitud de la cadena, como en el anuncio). Ver este enlace de wikipedia para obtener más detalles y Joel Spolsky excelente artículo para una introducción.


    Una interesante un lado por el camino. Se puede clasificar en bytes en un flujo UTF-8 como sigue:

    • Con el conjunto de bits a 0, es un valor de un byte.
    • Con los dos bits altos conjunto para 10, es una continuación de bytes.
    • De otro modo, es el primer byte de un multi-byte de la secuencia y el número de 1 bits indica cuántos bytes hay en total en esta secuencia (110... significa dos bytes, 1110... significa tres bytes, etc).
    • impresionante explicación. me ayudó mucho. gracias.

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea