UTF-8 es una forma relativamente simple de codificar puntos de código Unicode en un formato de ancho variable, de modo que no confunda fácilmente el código que no conoce Unicode.
Descripción general de UTF-8
- Los bytes en el rango de 1-0x7F, inclusive, son normalmente válidos
- Los bytes con el patrón de bits
10XX XXXX
se consideran bytes de continuación, y los seis bits menos significativos se utilizan para codificar parte de un punto de código. No deben aparecer a menos que sean esperados por un byte anterior. - Los bytes con el patrón
110X XXXX
esperan un byte de continuación después - Los bytes con el patrón
1110 XXXX
esperan dos bytes de continuación después - Los bytes con el patrón
1111 0XXX
esperan tres bytes de continuación después - Todos los demás bytes no son válidos y no deberían aparecer en ninguna parte de una secuencia UTF-8. Los grupos de 5, 6 y 7 bytes son posibles en teoría, pero no se permitirán a los efectos de este desafío.
Codificaciones demasiado largas
UTF-8 también requiere que un punto de código se represente con el número mínimo de bytes. Cualquier secuencia de bytes que pueda representarse con menos bytes no es válida. El UTF-8 modificado agrega una excepción a esto para los caracteres nulos (U + 0000), que deben representarse como C0 80
(representación hexadecimal), y en su lugar no permite que aparezcan bytes nulos en cualquier parte de la secuencia. (Esto lo hace compatible con cadenas terminadas en nulo)
Desafío
Debe crear un programa que, cuando se le dé una cadena de bytes, determinará si esa cadena representa UTF-8 modificado válido y devolverá un valor verdadero si es válido y un valor falso de lo contrario. Tenga en cuenta que debe verificar si hay codificaciones demasiado largas y bytes nulos (ya que se trata de UTF-8 modificado). No necesita decodificar los valores UTF-8.
Ejemplos
41 42 43 ==> yes (all bytes are in the 0-0x7F range)
00 01 02 ==> no (there is a null byte in the stream)
80 7F 41 ==> no (there is a continuation byte without a starter byte)
D9 84 10 ==> yes (the correct number of continuation bytes follow a starter byte)
F0 81 82 41 ==> no (there are not enough continuation bytes after F0)
EF 8A A7 91 ==> no (too many continuation bytes)
E1 E1 01 ==> no (starter byte where a continuation byte is expected)
E0 80 87 ==> no (overlong encoding)
41 C0 80 ==> yes (null byte encoded with the only legal overlong encoding)
F8 42 43 ==> no (invalid byte 'F8')
Reglas
- Aplican reglas estándar y lagunas
- La entrada y la salida pueden estar en cualquier formato conveniente siempre que se puedan leer todos los valores en el rango de bytes sin signo (0-255).
- Es posible que deba usar una matriz o un archivo en lugar de una cadena terminada en nulo. Debe poder leer bytes nulos.
- ¡El código más corto gana!
- Tenga en cuenta que el uso de incorporados para decodificar el UTF-8 no está garantizado para cumplir con los requisitos aquí establecidos. Es posible que deba solucionarlo y crear casos especiales.
EDITAR: bonificación adicional por no usar incorporados que decodifican UTF-8
EDIT2: se eliminó la bonificación ya que solo la respuesta de Rust calificó y es difícil de definir.
fuente
Respuestas:
Elixir , 69 bytes
Pruébalo en línea!
Utiliza la función de validación de cadena incorporada. Toma entrada como elixir binario.
fuente
APL (Dyalog Unicode) ,
41SBCS de 39 bytesFunción de prefijo tácito anónimo. Toma una cadena Unicode como argumento donde los puntos de código de los caracteres representan los bytes de entrada.
Pruébalo en línea!
'À\x80'⎕R⎕A
R eplaceC0 80
s con la mayúscula A lphabet{
...}
aplique la siguiente función anónima, donde el argumento es⍵
:0::
Si ocurre algún error:0
devolver cero⋄
tratar:⎕UCS⍵
convertir la cadena a puntos de código'UTF-8'⎕UCS⍣2
interpretar como bytes UTF-8 y convertir el texto resultante de nuevo a bytes⌊/
byte más bajo (cero si hay un byte nulo, positivo si no, "infinito" si una cadena vacía)×
signo (cero si el byte nulo está presente, uno si no)fuente
D9 C0 80 84 C0 80 10
?C0 80
hace que los bytes no relacionados sean adyacentes de una manera válida, aunque no son válidos cuando están separados? Editar: actualizado para solucionarlo sin costo de bytes.Python 2 ,
104102 bytesPruébalo en línea!
Salidas a través del código de salida
fuente
Óxido -
191 bytes313 bytesPor comentario debajo del original no funcionó correctamente. Versión nueva y mejorada. No se utilizan bibliotecas, porque The Mighty Rust no tiene necesidad de usted ni de sus bibliotecas. Este código utiliza la coincidencia de patrones con una máquina de estados. Al extraer descaradamente la especificación UTF8 , después de encontrarla por referencia y discusión por Jon Skeet , podemos copiar la especificación casi carácter por carácter en un bloque de coincidencia de patrón de coincidencia de óxido. Al final, agregamos el requisito especial Mutf8 de Beefster para que C0 80 se considere válido. Sin golf:
Pruébalo en el patio de óxido
fuente