online - send byte array in json c#




Datos binarios en cadena JSON. Algo mejor que Base64 (11)

( Edita 7 años después: Google Gears se ha ido. Ignora esta respuesta).

El equipo de Google Gears se encontró con el problema de la falta de tipos de datos binarios y ha intentado solucionarlo:

API de blob

JavaScript tiene un tipo de datos incorporado para cadenas de texto, pero nada para datos binarios. El objeto Blob intenta abordar esta limitación.

Tal vez puedas tejer eso de alguna manera.

El formato JSON de forma nativa no admite datos binarios. Los datos binarios deben escaparse para que puedan colocarse en un elemento de cadena (es decir, cero o más caracteres Unicode entre comillas dobles utilizando escapes de barra invertida) en JSON.

Un método obvio para escapar de los datos binarios es usar Base64. Sin embargo, Base64 tiene una alta sobrecarga de procesamiento. También expande 3 bytes en 4 caracteres, lo que lleva a un aumento en el tamaño de los datos en aproximadamente un 33%.

Un caso de uso para esto es el borrador v0.8 de la especificación de la API de almacenamiento en la nube CDMI . Usted crea objetos de datos a través de un servicio web REST usando JSON, por ejemplo

PUT /MyContainer/BinaryObject HTTP/1.1
Host: cloud.example.com
Accept: application/vnd.org.snia.cdmi.dataobject+json
Content-Type: application/vnd.org.snia.cdmi.dataobject+json
X-CDMI-Specification-Version: 1.0
{
    "mimetype" : "application/octet-stream",
    "metadata" : [ ],
    "value" :   "TWFuIGlzIGRpc3Rpbmd1aXNoZWQsIG5vdCBvbmx5IGJ5IGhpcyByZWFzb24sIGJ1dCBieSB0aGlz
    IHNpbmd1bGFyIHBhc3Npb24gZnJvbSBvdGhlciBhbmltYWxzLCB3aGljaCBpcyBhIGx1c3Qgb2Yg
    dGhlIG1pbmQsIHRoYXQgYnkgYSBwZXJzZXZlcmFuY2Ugb2YgZGVsaWdodCBpbiB0aGUgY29udGlu
    dWVkIGFuZCBpbmRlZmF0aWdhYmxlIGdlbmVyYXRpb24gb2Yga25vd2xlZGdlLCBleGNlZWRzIHRo
    ZSBzaG9ydCB2ZWhlbWVuY2Ugb2YgYW55IGNhcm5hbCBwbGVhc3VyZS4=",
}

¿Existen mejores formas y métodos estándar para codificar datos binarios en cadenas JSON?


BSON (Binary JSON) puede trabajar para usted. http://en.wikipedia.org/wiki/BSON

Edición: Para su información, la biblioteca .NET json.net admite la lectura y escritura de bson si está buscando algo de amor del lado del servidor C #.


El problema con UTF-8 es que no es la codificación más eficiente en espacio. Además, algunas secuencias de bytes binarios aleatorias son codificación UTF-8 no válida. Por lo tanto, no puede interpretar una secuencia de bytes binarios aleatorios como algunos datos UTF-8 porque será una codificación UTF-8 no válida. El beneficio de esta restricción en la codificación UTF-8 es que hace que sea robusto y posible ubicar los caracteres de múltiples bytes que comienzan y terminan cualquier byte que comencemos a observar.

Como consecuencia, si la codificación de un valor de byte en el rango [0..127] necesitaría solo un byte en la codificación UTF-8, la codificación de un valor de byte en el rango [128..255] requeriría 2 bytes! Peor que eso. En JSON, los caracteres de control "y \ no pueden aparecer en una cadena. Por lo tanto, los datos binarios requerirán que alguna transformación se codifique correctamente.

Vamos a ver. Si asumimos valores de bytes aleatorios distribuidos uniformemente en nuestros datos binarios, entonces, en promedio, la mitad de los bytes se codificarán en un byte y la otra mitad en dos bytes. Los datos binarios codificados en UTF-8 tendrían el 150% del tamaño inicial.

La codificación Base64 crece solo al 133% del tamaño inicial. Así que la codificación Base64 es más eficiente.

¿Qué hay de usar otra codificación Base? En UTF-8, la codificación de los 128 valores ASCII es la más eficiente en espacio. En 8 bits puedes almacenar 7 bits. Entonces, si cortamos los datos binarios en fragmentos de 7 bits para almacenarlos en cada byte de una cadena codificada en UTF-8, los datos codificados crecerán solo hasta el 114% del tamaño inicial. Mejor que Base64. Desafortunadamente, no podemos usar este truco fácil porque JSON no permite algunos caracteres ASCII. Los 33 caracteres de control de ASCII ([0..31] y 127) y el "y \ deben excluirse. Esto nos deja solo 128-35 = 93 caracteres.

Entonces, en teoría, podríamos definir una codificación Base93 que aumentaría el tamaño codificado a 8 / log2 (93) = 8 * log10 (2) / log10 (93) = 122%. Pero una codificación Base93 no sería tan conveniente como una codificación Base64. Base64 requiere cortar la secuencia de bytes de entrada en fragmentos de 6 bits para los cuales la operación simple a nivel de bits funciona bien. Al lado del 133% no es mucho más del 122%.

Esta es la razón por la que llegué independientemente a la conclusión común de que Base64 es la mejor opción para codificar datos binarios en JSON. Mi respuesta presenta una justificación para ello. Estoy de acuerdo en que no es muy atractivo desde el punto de vista del rendimiento, pero también considere el beneficio de usar JSON con su representación de cadena legible por humanos, fácil de manipular en todos los lenguajes de programación.

Si el rendimiento es crítico, una codificación binaria pura debe considerarse como reemplazo de JSON. Pero con JSON mi conclusión es que Base64 es el mejor.


El tipo de datos realmente preocupa. He probado diferentes escenarios al enviar la carga útil desde un recurso RESTful. Para la codificación he usado Base64 (Apache) y para compresión GZIP (java.utils.zip. *). La carga útil contiene información sobre una película, una imagen y un archivo de audio. He comprimido y codificado los archivos de imagen y audio que degradaron drásticamente el rendimiento. La codificación antes de la compresión resultó bien. La imagen y el contenido de audio se enviaron como bytes codificados y comprimidos [].


Mi solución ahora, XHR2 está utilizando ArrayBuffer. El ArrayBuffer como secuencia binaria contiene contenido de varias partes, video, audio, gráficos, texto, etc., con múltiples tipos de contenido. Todo en una respuesta.

En el navegador moderno, con DataView, StringView y Blob para diferentes componentes. Vea también: http://rolfrost.de/video.html para más detalles.


Sé que esta es una pregunta de casi 6 años, pero tengo el mismo problema y pensé que compartiría una solución: multipart / form-data.

Al enviar un formulario multiparte, primero envía como cadena sus metadatos JSON , y luego envía por separado como binario sin formato (imagen (es), wavs, etc.) indexado por el nombre de Disposición del contenido .

Aquí hay un buen tutorial sobre cómo hacer esto en obj-c, y aquí hay un artículo de blog que explica cómo particionar los datos de cadena con el límite del formulario y separarlos de los datos binarios.

El único cambio que realmente necesita hacer es en el lado del servidor; Tendrá que capturar sus metadatos que deben hacer referencia a los datos binarios de POST de forma adecuada (mediante el uso de un límite de contenido-Disposición).

Por supuesto, requiere un trabajo adicional en el lado del servidor, pero si está enviando muchas imágenes o imágenes grandes, vale la pena. Combina esto con la compresión gzip si quieres.

IMHO enviar datos codificados en base64 es un hack; RFC multipart / form-data se creó para problemas como este: el envío de datos binarios en combinación con texto o metadatos.


Si está utilizando Node, creo que la forma más eficiente y fácil es convertir a UTF16 con:

Buffer.from(data).toString('utf16le');

Puede recuperar sus datos por:

Buffer.from(s, 'utf16le');


Use base128, que en realidad puede producir una cadena JSON válida. AQUÍ ESTÁ TODO : todos los detalles y procedimientos JS para codificar / descodificar (la matriz de la base128 de salida es un 15% más grande que la matriz de bytes de entrada)


Ya que busca la capacidad de adaptar los datos binarios en un formato estrictamente basado en texto y muy limitado, creo que la sobrecarga de Base64 es mínima en comparación con la conveniencia que espera mantener con JSON. Si la capacidad de procesamiento y el rendimiento son una preocupación, entonces probablemente deba reconsiderar sus formatos de archivo.


Formato de sonrisa

Es muy rápido para codificar, decodificar y compactar

Comparación de velocidad (basada en java pero significativa): https://github.com/eishay/jvm-serializers/wiki/

También es una extensión de JSON que le permite omitir la codificación base64 para matrices de bytes.

Las cadenas codificadas con sonrisa se pueden comprimir cuando el espacio es crítico





base64