Eu estava lendo a documentação para StringBuffer
, em particular o método reverse () . Essa documentação menciona algo sobre pares substitutos . O que é um par substituto nesse contexto? E o que são substitutos baixos e altos ?
java
unicode
utf-16
surrogate-pairs
Raymond
fonte
fonte
String
que sejam feitos, não apenas de unidades de caracteres. Pena que o Java não permite que você use OO para corrigir isso, mas aString
classe e asStringBuffer
classes foramfinal
dimensionadas. Diga, isso não é um eufemismo para mortos? :)Respostas:
O termo "par substituto" refere-se a um meio de codificação de caracteres Unicode com altos pontos de código no esquema de codificação UTF-16.
Na codificação de caracteres Unicode, os caracteres são mapeados para valores entre 0x0 e 0x10FFFF.
Internamente, Java usa o esquema de codificação UTF-16 para armazenar seqüências de caracteres de texto Unicode. No UTF-16, são utilizadas unidades de código de 16 bits (dois bytes). Como 16 bits podem conter apenas o intervalo de caracteres de 0x0 a 0xFFFF, alguma complexidade adicional é usada para armazenar valores acima desse intervalo (0x10000 a 0x10FFFF). Isso é feito usando pares de unidades de código conhecidas como substitutos.
As unidades de código substituto estão em dois intervalos conhecidos como "substitutos altos" e "substitutos baixos", dependendo de serem permitidos no início ou no final da sequência da unidade de dois códigos.
fonte
As versões anteriores do Java representavam caracteres Unicode usando o tipo de dados char de 16 bits. Esse design fazia sentido no momento, porque todos os caracteres Unicode tinham valores menores que 65.535 (0xFFFF) e podiam ser representados em 16 bits. Mais tarde, no entanto, o Unicode aumentou o valor máximo para 1.114.111 (0x10FFFF). Como os valores de 16 bits eram muito pequenos para representar todos os caracteres Unicode na versão 3.1, os valores de 32 bits - chamados pontos de código - foram adotados para o esquema de codificação UTF-32. Mas os valores de 16 bits são preferidos aos valores de 32 bits para um uso eficiente da memória; portanto, o Unicode introduziu um novo design para permitir o uso continuado dos valores de 16 bits. Esse design, adotado no esquema de codificação UTF-16, atribui 1.024 valores a substitutos altos de 16 bits (no intervalo U + D800 a U + DBFF) e outros 1.024 valores a substitutos baixos de 16 bits (no intervalo U + DC00 para U + DFFF).
fonte
O que essa documentação está dizendo é que cadeias UTF-16 inválidas podem se tornar válidas após a chamada do
reverse
método, pois podem ser o inverso de cadeias válidas. Um par substituto (discutido aqui ) é um par de valores de 16 bits no UTF-16 que codifica um único ponto de código Unicode; os substitutos baixos e altos são as duas metades dessa codificação.fonte
Adicionando mais algumas informações às respostas acima deste post.
Testado em Java-12, deve funcionar em todas as versões Java acima de 5.
Conforme mencionado aqui: https://stackoverflow.com/a/47505451/2987755 ,
o caractere (cujo Unicode está acima de U + FFFF) é representado como um par substituto, que Java armazena como um par de valores de caracteres, ou seja, o único Unicode caractere é representado como dois caracteres Java adjacentes.
Como podemos ver no exemplo a seguir.
1. comprimento:
2. Igualdade:
represente "🌉" para String usando Unicode
\ud83c\udf09
como abaixo e verifique a igualdade.Java não suporta UTF-32
3. Você pode converter caracteres Unicode em Java String
4. String.substring () não considera caracteres suplementares
Para resolver isso, podemos usar
String.offsetByCodePoints(int index, int codePointOffset)
5. corda Iterating Unicode com BreakIterator
6. Sorting Cordas com Unicode java.text.Collator
7. do personagem
toUpperCase()
,toLowerCase()
, métodos não deve ser usado, em vez disso, maiúscula uso de Cordas e minúsculas de particular localidade.8.
Character.isLetter(char ch)
não suporta, melhor usadoCharacter.isLetter(int codePoint)
, para cadamethodName(char ch)
método na classe Caractere, haverá um tipomethodName(int codePoint)
que pode manipular caracteres suplementares.9. Especificar conjunto de caracteres em
String.getBytes()
, conversão de Bytes para String,InputStreamReader
,OutputStreamWriter
Ref:
https://coolsymbol.com/emojis/emoji-for-copy-and-paste.html#objects
https://www.online-toolz.com/tools/text-unicode-entities-convertor.php
https: //www.ibm.com/developerworks/library/j-unicode/index.html
https://www.oracle.com/technetwork/articles/javaee/supplementary-142654.html
Mais informações sobre o exemplo image1 image2
Outros termos que vale a pena explorar: Normalização , BiDi
fonte
Pares substitutos se referem à maneira de codificar certos caracteres do UTF-16, consulte http://en.wikipedia.org/wiki/UTF-16/UCS-2#Code_points_U.2B10000..U.2B10FFFF
fonte
Prefácio pequeno
Antes da versão 3.1, o uso mais comum era o encconding de 8 bits, conhecido como UTF-8, e a codificação de 16 bits, conhecida como UCS-2 ou "Conjunto Universal de Caracteres codificado em 2 octetos". UTF-8 codifica pontos Unicode como uma sequência de blocos de 1 byte, enquanto o UCS-2 sempre leva 2 bytes:
A = 41 - um bloco de 8 bits com UTF-8
A = 0041 - um bloco de 16 bits com UCS-2
Ω = CE A9 - dois blocos de 8 bits com UTF-8
Ω = 03A9 - um bloco de 16 bits com UCS-2
Problema
O consórcio achou que 16 bits seriam suficientes para cobrir qualquer linguagem legível por humanos, o que fornece 2 ^ 16 = 65536 possíveis valores de código. Isso era verdade para o Plano 0, também conhecido como BPM ou Plano Multilíngue Básico, que inclui 55.445 de 65536 pontos de código hoje. O BPM cobre quase todas as línguas humanas do mundo, incluindo símbolos chinês-japonês-coreano (CJK).
O tempo passou e novos conjuntos de caracteres asiáticos foram adicionados; os símbolos chineses ocuparam mais de 70.000 pontos. Agora, existem até pontos Emoji como parte do padrão 😺. Novos 16 aviões "adicionais" foram adicionados. A sala UCS-2 não era suficiente para cobrir algo maior que o avião 0.
Decisão Unicode
Crie UTF-16 com base no UCS-2. Faça o UTF-16 dinâmico, para que ele use 2 bytes ou 4 bytes por ponto. Atribua 1024 pontos U + D800 – U + DBFF, chamados Altos Substitutos, a UTF-16; atribua 1024 símbolos U + DC00 – U + DFFF, chamados substitutos baixos, a UTF-16.
Com essas alterações, o BPM é coberto com 1 bloco de 16 bits em UTF-16, enquanto todos os "caracteres suplementares" são cobertos com pares substitutos que apresentam 2 blocos por 16 bits cada, totalmente 1024x1024 = 1.048.576 pontos.
Um substituto alto precede um substituto baixo . Qualquer desvio desta regra é considerado como uma codificação incorreta. Por exemplo, um substituto sem um par está incorreto, um substituto baixo está em pé antes que um substituto alto esteja incorreto.
𝄞, 'MUSICAL SYMBOL G CLEF', é codificado em UTF-16 como um par de substitutos 0xD834 0xDD1E (2 por 2 bytes),
em UTF-8 como 0xF0 0x9D 0x84 0x9E (4 por 1 byte),
em UTF-32 como 0x0001D11E (1 por 4 bytes).
Situação atual
Para dar suporte a aplicativos legados com codificações UTF-8 / UTF-16 incorretas , foi criado um novo WTF-8 padrão , o Wobbly Transformation Format. Ele suporta pontos substitutos arbitrários, como um substituto não emparelhado ou uma sequência incorreta. Hoje, alguns produtos não estão em conformidade com o padrão e tratam o UTF-8 como WTF-8.
Muitos detalhes históricos foram suprimidos para seguir o tópico ⚖.
O último padrão Unicode pode ser encontrado em http://www.unicode.org/versions/latest
fonte
Um par substituto é duas 'unidades de código' em UTF-16 que compõem um 'ponto de código'. A documentação Java está afirmando que esses 'pontos de código' ainda serão válidos, com suas 'unidades de código' ordenadas corretamente, após o inverso. Afirma ainda que duas unidades de código substituto não emparelhadas podem ser revertidas e formar um par substituto válido. O que significa que, se houver unidades de código não emparelhadas, existe a chance de o inverso do reverso não ser o mesmo!
Observe, porém, que a documentação não diz nada sobre Graphemes - que são vários pontos de código combinados. O que significa que e o sotaque que o acompanha ainda pode ser alterado, colocando assim o sotaque antes do e. O que significa que, se houver outra vogal antes do e, poderá obter o sotaque que estava no e.
Caramba!
fonte