que number non hace ejemplos codigo characters accented unicode utf-8 utf-16

number - Conversión manual de puntos de código Unicode en UTF-8 y UTF-16



unicode characters java (3)

Tengo un examen de programación universitaria que viene, y una sección está en Unicode.

He revisado todas las respuestas y mi profesor es inútil, así que no sirve de nada, así que este es un último recurso para que ustedes puedan ayudar.

La pregunta será algo así como:

La cadena ''mЖ 丽'' tiene estos puntos de código Unicode U+006D , U+0416 y U+4E3D , con las respuestas escritas en hexadecimal, codifican manualmente la cadena en UTF-8 y UTF-16.

Cualquier ayuda será muy apreciada ya que estoy tratando de entender esto.


El siguiente programa hará el trabajo necesario. Puede que no sea lo suficientemente "manual" para sus propósitos, pero como mínimo puede verificar su trabajo.

#!/usr/bin/perl use 5.012; use strict; use utf8; use autodie; use warnings; use warnings qw< FATAL utf8 >; no warnings qw< uninitialized >; use open qw< :std :utf8 >; use charnames qw< :full >; use feature qw< unicode_strings >; use Encode qw< encode decode >; use Unicode::Normalize qw< NFD NFC >; my ($x) = "mЖ丽"; open(U8,">:encoding(utf8)","/tmp/utf8-out"); print U8 $x; close(U8); open(U16,">:encoding(utf16)","/tmp/utf16-out"); print U16 $x; close(U16); system("od -t x1 /tmp/utf8-out"); my $u8 = encode("utf-8",$x); print "utf-8: 0x".unpack("H*",$u8)."/n"; system("od -t x1 /tmp/utf16-out"); my $u16 = encode("utf-16",$x); print "utf-16: 0x".unpack("H*",$u16)."/n";


Guau. Por un lado, estoy encantado de saber que los cursos universitarios enseñan a la realidad que las codificaciones de caracteres son un trabajo duro, pero conocer las reglas de codificación UTF-8 suena como esperar mucho. (¿Ayudará a los estudiantes a pasar la prueba de Turquía ?)

La descripción más clara que he visto hasta ahora de las reglas para codificar los puntos de código UCS para UTF-8 proviene de la página de utf-8(7) en muchos sistemas Linux:

Encoding The following byte sequences are used to represent a character. The sequence to be used depends on the UCS code number of the character: 0x00000000 - 0x0000007F: 0xxxxxxx 0x00000080 - 0x000007FF: 110xxxxx 10xxxxxx 0x00000800 - 0x0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx 0x00010000 - 0x001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx [... removed obsolete five and six byte forms ...] The xxx bit positions are filled with the bits of the character code number in binary representation. Only the shortest possible multibyte sequence which can represent the code number of the character can be used. The UCS code values 0xd800–0xdfff (UTF-16 surrogates) as well as 0xfffe and 0xffff (UCS noncharacters) should not appear in conforming UTF-8 streams.

Puede ser más fácil recordar una versión ''comprimida'' del gráfico:

Los inicios de bytes iniciales de puntos de código mutilados comienzan con un 1 y agregan relleno 1+0 . Los bytes subsiguientes comienzan 10 .

0x80 5 bits, one byte 0x800 4 bits, two bytes 0x10000 3 bits, three bytes

Puede derivar los rangos tomando nota de la cantidad de espacio que puede llenar con los bits permitidos en la nueva representación:

2**(5+1*6) == 2048 == 0x800 2**(4+2*6) == 65536 == 0x10000 2**(3+3*6) == 2097152 == 0x200000

que podría recordar las reglas para derivar el gráfico más fácil que el gráfico en sí. Aquí está la esperanza de que seas bueno recordando las reglas también. :)

Actualizar

Una vez que haya creado el cuadro anterior, puede convertir los puntos de código de entrada Unicode en UTF-8 buscando su rango, convirtiendo de hexadecimal a binario, insertando los bits según las reglas anteriores y luego convirtiendo de nuevo a hexadecimal:

U+4E3E

Esto se ajusta en el rango 0x00000800 - 0x0000FFFF ( 0x4E3E < 0xFFFF ), por lo que la representación será de la siguiente forma:

1110xxxx 10xxxxxx 10xxxxxx

0x4E3E es 100111000111110b . Suelta los bits en la x arriba (empieza desde la derecha, llenaremos los bits que faltan al comienzo con 0 ):

1110x100 10111000 10111110

Al comienzo hay un punto x , llene con 0 :

11100100 10111000 10111110

Convierta de bits a hex :

0xE4 0xB8 0xBE


Las descripciones en Wikipedia para UTF-8 y UTF-16 son buenas:

Procedimientos para su cadena de ejemplo:

UTF-8

UTF-8 usa hasta 4 bytes para representar puntos de código Unicode. Para el caso de 1 byte, use el siguiente patrón:

1-byte UTF-8 = 0xxxxxxx bin = 7 bits = 0-7F hex.

El byte inicial de 2, 3 y 4 bytes UTF-8 comienza con 2, 3 o 4 bits, seguido de un bit cero. Seguir en bytes siempre comienza con el patrón de dos bits 10 , dejando 6 bits para los datos:

2-byte UTF-8 = 110xxxxx 10xxxxxx bin = 5 + 6 (11) bits = 80-7FF hex
3-byte UTF-8 = 1110xxxx 10xxxxxx 10xxxxxx bin = 4 + 6 + 6 (16) bits = 800-FFFF hex
4-byte UTF-8 = 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx bin = 3 + 6 + 6 + 6 (21) bits = 10000-10FFFF hex.

† Los puntos de código Unicode no están definidos más allá de 10FFFF hex .

Sus puntos de código son U + 006D, U + 0416 y U + 4E3D que requieren secuencias de UTF-8 de 1, 2 y 3 bytes, respectivamente. Convierte a binario y asigna los bits:

U + 006D = 1101101 bin = 0 1101101 bin = 6D hex
U + 0416 = 10000 010110 bin = 110 10000 10 010110 bin = D0 96 hex
U + 4E3D = 0100 111000 111101 bin = 1110 0100 10 111000 10 111101 bin = E4 B8 BD hex

Secuencia de bytes final:

6D D0 96 E4 B8 BD

o si se desean cadenas terminadas en nulo:

6D D0 96 E4 B8 BD 00

UTF-16

UTF-16 usa 2 o 4 bytes para representar puntos de código Unicode. Algoritmo:

U + 0000 a U + D7FF usa 2 bytes byte 0000 hex a D7FF hex
U + D800 a U + DFFF son puntos de código no válidos reservados para 4 bytes UTF-16
U + E000 a U + FFFF utiliza 2-byte E000 hex a FFFF hex

U + 10000 a U + 10FFFF usa un UTF-16 de 4 bytes codificado de la siguiente manera:

  1. Reste 10000 hex desde el punto de código.
  2. Resultado expreso como binario de 20 bits.
  3. Use el patrón 110110xxxxxxxxxx 110111xxxxxxxxxx bin para codificar los 10 bits superiores e inferiores en dos palabras de 16 bits.

Usando tus puntos de código:

U + 006D = 006D hex
U + 0416 = 0416 hex
U + 4E3D = 4E3D hex

Ahora, tenemos un problema más. Algunas máquinas almacenan primero los dos bytes de una palabra de 16 bits de menor significado significativo (las llamadas máquinas little-endian) y algunas almacenan primero el byte más significativo (máquinas big-endian). UTF-16 usa el punto de código U + FEFF (llamado marca de orden de byte o BOM) para ayudar a una máquina a determinar si una secuencia de bytes contiene UTF-16 grande o pequeño endian:

big-endian = FE FF 00 6D 04 16 4E 3D
little-endian = FF FE 6D 00 16 04 3D 4E

Con nul-terminación, U + 0000 = 0000 hex :

big-endian = FE FF 00 6D 04 16 4E 3D 00 00
little-endian = FF FE 6D 00 16 04 3D 4E 00 00

Dado que su instructor no dio un código que requirió 4 bytes UTF-16, aquí hay un ejemplo:

U + 1F031 = 1F031 hex - 10000 hex = F031 hex = 0000111100 0000110001 bin =
110110 0000111100 110111 0000110001 bin = D83C DC31 hex