2012-06-14 13 views
9

Asumiendo codificación UTF-8 y strlen() en PHP, ¿es posible que esta cadena tenga una longitud de 4?strlen() y codificación UTF-8

sólo me interesa saber sobre strlen(), no otras funciones

Esta es la cadena: $ 1�2

que he probado en mi propio ordenador, y me han verificado UTF -8 codificación, y la respuesta que obtengo es 6.

No veo nada en el manual de strlen ni nada que haya leído en UTF-8 que explique por qué algunos de los caracteres anteriores contarían por menos de una.

PD: Esta pregunta y respuesta (4) viene de una prueba de simulación para ZCE que compré en Ebay.

PPS: Por favor, tírame un hueso y vota esto. Hice mis deberes. Gracias de antemano por todas las respuestas y votos.

+4

'strlen' cuenta bytes, no caracteres – Esailija

+0

Los caracteres UTF-8 son caracteres multibyte, y cuentan como as-many-characters-as-they-are-long-in-bytes cuando se usa' strlen'. Use http://php.net/manual/en/function.mb-strlen.php para obtener los resultados esperados. –

+4

Los caracteres codificados @RemcoOverdijk utf-8 pueden tener entre 1 y 6 bytes de longitud. – Esailija

Respuesta

8

La cadena informados es de seis caracteres de largo: $ 1�2 (signo del dólar, uno ', y i minúscula con diéresis marca, al revés pregunta, una fracción media, dos dígitos)

Si strlen() fue llamado con una representación UTF-8 de esa cadena, obtendría un resultado de nueve (probablemente, aunque haya múltiples representaciones con diferentes longitudes).

Sin embargo, si tuviéramos que almacenar esa cadena como ISO 8859-1 o CP1252, tendríamos una secuencia de seis bytes que sería legal como UTF-8. La reinterpretación de esos 6 bytes como UTF-8 daría como resultado 4 caracteres: $ 1 2 (signo de dólar, dígito uno, carácter de reemplazo Unicode, dígito 2). Es decir, la codificación UTF-8 del carácter único ' ' es idéntica a la codificación ISO-8859-1 de los tres caracteres "�".

El carácter de reemplazo a menudo se inserta cuando un decodificador UTF-8 lee datos que no son válidos para UTF-8.

Parece que la cadena original se procesó a través de varias capas de interpretación errónea; mediante el uso de un decodificador UTF-8 en datos que no sean UTF-8 (produciendo $ 1 2), y luego por lo que sea que haya utilizado para analizar esa información (produciendo $ 1 ¿2).

15

¿qué tal el uso de mb_strlen()?

http://lt.php.net/manual/en/function.mb-strlen.php

Pero si es necesario utilizar strlen, es posible configurar el servidor web mediante el establecimiento de Directiva mbstring.func_overload a 2, por lo que reemplazará automáticamente de strlen a mb_strlen en los scripts.

+1

sí, vi mb_strlen() en otras respuestas, pero estoy buscando específicamente strlen() –

+0

corrigió mi respuesta para responder a tu pregunta. – Anton

+0

gracias. no responde la pregunta lo siento. –

1

Muchos caracteres UTF-8 toman varios bytes en lugar de uno. Así es como se construye UTF-8 (así es como puedes tener tantos personajes en un solo conjunto).

Pruebe mb_strlen() en su lugar.

+0

fun-fact: en teoría, utf-8 puede usar hasta 8 bytes por carácter, aunque esta lenth no se usa hasta ahora; la longitud máxima utilizada es un grupo de caracteres de cuatro bytes (como el signo de clave y algunos Caracteres chinos, por ejemplo). – oezi

+0

¿qué pasa con strlen(), es posible que la respuesta sea menor que 6? –

+0

@JonLyles: 'strlen()' cuenta los bytes en la cadena.Si la cadena tiene 6 bytes, dará como resultado 6. –

5

necesidad de utilizar varios bytes Cadena Función mb_strlen() como:

mb_strlen($string, 'UTF-8'); 
2

Voy a usar una prueba por la contradicción.

strlen cuenta los bytes, por lo que con un strlen de 4, debería haber exactamente 4 bytes en esa cadena.

La codificación UTF8 necesita al menos 1 byte por carácter.

Hemos establecido que:

  1. hay 4 bytes
  2. un personaje está representado por no menos de 1 byte

... sin embargo, tenemos 6 caracteres ... .que es una contradicción. Entonces, no.

Sin embargo, lo que no está del todo claro es qué conjunto de caracteres utiliza el software de visualización (por ejemplo, el navegador web) para interpretar la cadena. Podría usar un esquema de codificación poco común donde un personaje puede representarse con menos de 8 bits. Si este fuera el caso, entonces 4 bytes podrían mostrarse como 6 caracteres. Entonces, la cadena podría ser utf8, pero el navegador podría decidir interpretarla como, por ejemplo, un conjunto de caracteres de 5 bits.

+0

buena información. gracias. –

5

Es probable que en algún momento entre la preparación de la pregunta y su lectura del mismo, algún proceso haya mutilado caracteres no ASCII, por lo que la pregunta fue originalmente sobre una cadena con 4 caracteres.

La secuencia � se obtiene cuando codifica el replacement character U+FFFD () en UTF-8 e interpreta el resultado en latin1. Este carácter se usa como un reemplazo para las secuencias de bytes que no codifican ningún carácter cuando se lee texto de un archivo, por ejemplo. Lo que ha sucedido es probable que esto:

La pregunta original, almacenado en un archivo de texto latin1, tenían: $1¢2 (se puede reemplazar ¢ con cualquier carácter no ASCII)

El archivo fue leído por un programa que utiliza UTF-8. Como el byte correspondiente a ¢ no se pudo interpretar, el programa lo sustituyó y leyó el texto $1�2. Este texto luego se escribió usando UTF-8, lo que resultó en $1\xEF\xBF\xBD2 en el archivo.

Luego viene un tercer programa que lee el archivo en latin1, y muestra $1�2.

+0

muy útil gracias –