Tengo algunos datos codificados en UTF-8 que viven en un rango de elementos Uint8Array en Javascript. ¿Existe una forma eficiente de decodificarlos en una cadena javascript normal (creo que Javascript usa Unicode de 16 bits)? No quiero agregar un carácter a la vez ya que la concatenación de cadenas se volvería intensiva en la CPU.
javascript
Jack Wester
fuente
fuente
u8array.toString()
cuando leo archivos de BrowserFS que exponen el objeto Uint8Array cuando llamasfs.readFile
.toString
enUint8Array
devuelve números separados por comas como"91,50,48,49,57,45"
(Chrome 79)Respuestas:
TextEncoder
yTextDecoder
del estándar Encoding , que está polyrellenado por la biblioteca stringencoding , convierte entre cadenas y ArrayBuffers:fuente
npm install text-encoding
,var textEncoding = require('text-encoding'); var TextDecoder = textEncoding.TextDecoder;
. No, gracias.utf-8
. Entonces, ¡elTextEncoder
argumento es innecesario!TextEncoder
/TextDecoder
API en v11, por lo que no es necesario instalar ningún paquete adicional si solo apunta a las versiones actuales de Node.Esto debería funcionar:
Es algo más limpio que las otras soluciones porque no usa ningún truco ni depende de las funciones del navegador JS, por ejemplo, también funciona en otros entornos JS.
Consulte la demostración de JSFiddle .
Consulte también las preguntas relacionadas: aquí y aquí
fuente
fromUTF8Array([240,159,154,133])
resulta vacío (mientrasfromUTF8Array([226,152,131])→"☃"
)Esto es lo que uso:
fuente
RangeError
textos más grandes. "Se superó el tamaño máximo de la pila de llamadas"SCRIPT28: Out of stack space
cuando le doy 300 + k caracteres, oRangeError
para Chrome 39. Firefox 33 está bien. 100 + k funciona bien con los tres.Se encuentra en una de las aplicaciones de muestra de Chrome, aunque está destinado a bloques de datos más grandes en los que está de acuerdo con una conversión asincrónica.
fuente
En Nodo, las "
Buffer
instancias también sonUint8Array
instancias ", por lo quebuf.toString()
funciona en este caso.fuente
Buffer
que también es Uint8Array. ¡Gracias!Buffer.from(uint8array).toString('utf-8')
La solución proporcionada por Albert funciona bien siempre y cuando la función proporcionada se invoque con poca frecuencia y solo se use para matrices de tamaño modesto; de lo contrario, es extremadamente ineficiente. Aquí hay una solución de JavaScript vainilla mejorada que funciona tanto para Node como para navegadores y tiene las siguientes ventajas:
• Funciona de manera eficiente para todos los tamaños de matriz de octetos
• No genera cadenas intermedias desechables
• Admite caracteres de 4 bytes en motores JS modernos (de lo contrario, se sustituye "?")
fuente
Haga lo que dijo @Sudhir, y luego para obtener una cadena de la lista de números separados por comas, use:
Esto le dará la cadena que desea, si aún es relevante
fuente
String.fromCharCode.apply(null, unitArr);
. Como se mencionó, no maneja la codificación UTF8, pero a veces esto es lo suficientemente simple si solo necesita soporte ASCII pero no tiene acceso a TextEncoder / TextDecoder.Si no puede usar la API TextDecoder porque no es compatible con IE :
fuente
Prueba estas funciones,
fuente: https://gist.github.com/tomfa/706d10fed78c497731ac , felicitaciones a Tomfa
fuente
Me frustró ver que la gente no mostraba cómo ir en ambos sentidos o mostraba que las cosas no funcionan en cadenas UTF8 triviales. Encontré una publicación en codereview.stackexchange.com que tiene un código que funciona bien. Lo usé para convertir runas antiguas en bytes, para probar algunas criptomonedas en los bytes y luego convertir las cosas en una cadena. El código de trabajo está en github aquí . Cambié el nombre de los métodos para mayor claridad:
La prueba unitaria utiliza esta cadena UTF-8:
Tenga en cuenta que la longitud de la cadena es de solo 117 caracteres, pero la longitud del byte, cuando se codifica, es de 234.
Si elimino el comentario de las líneas de console.log, puedo ver que la cadena que se decodifica es la misma cadena que se codificó (¡con los bytes pasados a través del algoritmo de intercambio secreto de Shamir!):
fuente
String.fromCharCode.apply(null, chars)
Error sichars
es demasiado grande.En NodeJS, tenemos búferes disponibles y la conversión de cadenas con ellos es realmente fácil. Mejor aún, es fácil convertir un Uint8Array en un búfer. Pruebe este código, me funcionó en Node básicamente para cualquier conversión que involucre Uint8Arrays:
Solo estamos extrayendo el ArrayBuffer de Uint8Array y luego convirtiéndolo en un NodeJS Buffer adecuado. Luego, convertimos el búfer en una cadena (puede incluir una codificación hexadecimal o base64 si lo desea).
Si queremos volver a convertir a Uint8Array desde una cadena, haríamos esto:
Tenga en cuenta que si declaró una codificación como base64 al convertir a una cadena, entonces tendría que usar
Buffer.from(str, "base64")
si usó base64, o cualquier otra codificación que haya usado.¡Esto no funcionará en el navegador sin un módulo! Los búferes de NodeJS simplemente no existen en el navegador, por lo que este método no funcionará a menos que agregue la funcionalidad de búfer al navegador. Sin embargo, eso es bastante fácil de hacer, solo use un módulo como este , que es pequeño y rápido.
fuente
'
fuente
Estoy usando este fragmento de Typecript:
Elimine las anotaciones de tipo si necesita la versión de JavaScript. ¡Espero que esto ayude!
fuente