Tenho alguns dados codificados em UTF-8 em uma variedade de elementos Uint8Array em Javascript. Existe uma maneira eficiente de decodificá-los em uma string javascript regular (acredito que o Javascript usa Unicode de 16 bits)? Não quero adicionar um caractere de cada vez, pois a concatenação de strings se tornaria muito intensa na CPU.
javascript
Jack Wester
fonte
fonte
u8array.toString()
ao ler arquivos do BrowserFS que expõem o objeto Uint8Array quando você chamafs.readFile
.toString
emUint8Array
volta números separados por vírgulas, tais como"91,50,48,49,57,45"
(79 Chrome)Respostas:
TextEncoder
eTextDecoder
do padrão de codificação , que é polyfilled pela biblioteca stringencoding , converte entre strings e ArrayBuffers:fonte
npm install text-encoding
,var textEncoding = require('text-encoding'); var TextDecoder = textEncoding.TextDecoder;
. Não, obrigado.utf-8
. Portanto, oTextEncoder
argumento é desnecessário!TextEncoder
/TextDecoder
APIs na v11, portanto, não há necessidade de instalar nenhum pacote extra se você direcionar apenas as versões atuais do Node.Isso deve funcionar:
É um pouco mais limpo como as outras soluções porque não usa nenhum hacks nem depende das funções do navegador JS, por exemplo, funciona também em outros ambientes JS.
Confira a demonstração JSFiddle .
Veja também as questões relacionadas: aqui e aqui
fonte
fromUTF8Array([240,159,154,133])
fica vazio (enquantofromUTF8Array([226,152,131])→"☃"
)Aqui está o que eu uso:
fonte
RangeError
textos maiores. "Tamanho máximo da pilha de chamadas excedido"SCRIPT28: Out of stack space
quando eu o alimentar com 300 + k caracteres, ouRangeError
para o Chrome 39. Firefox 33 está ok. 100 + k funciona bem com todos os três.Encontrado em um dos aplicativos de amostra do Chrome, embora seja destinado a grandes blocos de dados em que você está bem com uma conversão assíncrona.
fonte
No Node "
Buffer
instâncias também sãoUint8Array
instâncias ", entãobuf.toString()
funciona neste caso.fonte
Buffer
também é Uint8Array. Obrigado!Buffer.from(uint8array).toString('utf-8')
A solução fornecida por Albert funciona bem, desde que a função fornecida seja invocada com pouca frequência e seja usada apenas para arrays de tamanho modesto, caso contrário, é notoriamente ineficiente. Aqui está uma solução JavaScript vanilla aprimorada que funciona para Node e navegadores e tem as seguintes vantagens:
• Funciona de forma eficiente para todos os tamanhos de matriz de octeto
• Não gera strings descartáveis intermediárias
• Suporta caracteres de 4 bytes em motores JS modernos (caso contrário, "?" É substituído)
fonte
Faça o que @Sudhir disse e, para obter uma string da lista de números separados por vírgulas, use:
Isso lhe dará a string que você deseja, se ainda for relevante
fonte
String.fromCharCode.apply(null, unitArr);
. Conforme mencionado, ele não lida com a codificação UTF8, mas às vezes isso é simples o suficiente se você precisar apenas de suporte ASCII, mas não tiver acesso a TextEncoder / TextDecoder.Se você não puder usar a API TextDecoder porque ela não é compatível com o IE :
fonte
Experimente essas funções,
fonte: https://gist.github.com/tomfa/706d10fed78c497731ac , parabéns para Tomfa
fonte
Fiquei frustrado ao ver que as pessoas não estavam mostrando como fazer as duas coisas ou mostrando que as coisas funcionam em strings UTF8 não triviais. Eu encontrei uma postagem no codereview.stackexchange.com que contém um código que funciona bem. Usei-o para transformar runas antigas em bytes, para testar alguns crypo nos bytes e, em seguida, converter as coisas de volta em uma string. O código de trabalho está no github aqui . Renomeei os métodos para maior clareza:
O teste de unidade usa esta string UTF-8:
Observe que o comprimento da string é de apenas 117 caracteres, mas o comprimento do byte, quando codificado, é 234.
Se eu descomentar as linhas console.log, posso ver que a string decodificada é a mesma string que foi codificada (com os bytes passados pelo algoritmo de compartilhamento secreto de Shamir!):
fonte
String.fromCharCode.apply(null, chars)
irá errar sechars
for muito grande.No NodeJS, temos Buffers disponíveis, e a conversão de strings com eles é realmente fácil. Melhor, é fácil converter um Uint8Array em Buffer. Tente este código, ele funcionou para mim no Node para basicamente qualquer conversão envolvendo Uint8Arrays:
Estamos apenas extraindo o ArrayBuffer do Uint8Array e, em seguida, convertendo-o em um Buffer NodeJS adequado. Em seguida, convertemos o Buffer em uma string (você pode adicionar uma codificação hex ou base64, se desejar).
Se quisermos converter de volta para um Uint8Array a partir de uma string, faremos o seguinte:
Esteja ciente de que se você declarou uma codificação como base64 ao converter para uma string, então você teria que usar
Buffer.from(str, "base64")
se usou base64, ou qualquer outra codificação que você usou.Isso não funcionará no navegador sem um módulo! Buffers NodeJS simplesmente não existem no navegador, portanto, este método não funcionará a menos que você adicione a funcionalidade Buffer ao navegador. Na verdade, isso é muito fácil de fazer, basta usar um módulo como este , que é pequeno e rápido!
fonte
`
fonte
Estou usando este snippet de Typescript:
Remova as anotações de tipo se precisar da versão JavaScript. Espero que isto ajude!
fonte