[Volver al Índice de Este Documento]
[Volver al Índice del Sitio]

Conversión de Strings a Bytes





En navegadores modernos, JavaScript no codifica las cadenas de texto con 1 byte por carácter, sino más bien con por lo menos 4 bytes por carácter (ya que hay caracteres que necesitan hasta 3 bytes para codificar su valor Unicode, y se necesita un valor eficiente potencia de 2 para determinar rápidamente posiciones de caracteres y longitudes de cadena).

Este hecho parece irrelevante, pero tan pronto como deseamos enviar datos crudos a, por ejemplo, un formulario que recibe un script de PHP y que contiene caracteres especiales, el texto que escribimos se corrompe. O si intentamos codificar este tipo de datos a Base64 con la función btoa, se produce un error de ejecución.

Esto es porque JavaScript sigue tratando los datos con valores de los caracteres de la cadena como de más de 8 bits por byte, por lo que es posible todo tipo de corrupción en cada carácter y errores de ejecución.

__________________________
__________________________
__________________________

La solución es simple, pero debemos razonarla:

- Paso 1: Necesitamos usar una función que descomponga los valores de cada carácter en los valores de bytes que lo conforman, expresados en secuencias de escape de URI (esto solo es necesario en JavaScript, pero no en otros lenguajes de más bajo nivel como C).

- Paso 2: Necesitamos una función que, en lugar de convertir las secuencias de escape de URI en caracteres de más de 8 bits, conviertan cada carácter escapado en un valor de 8 bits individual.

Para el Paso 1, la función a usar es encodeURIComponent, que es capaz de convertir caracteres Unicode en secuencias de escape para cada byte de cada carácter multibyte.

Para el Paso 2, la función a usar es unescape, la cual (en este contexto) solamente puede manejar valores de caracteres de hasta 8 bits. Por lo tanto, al decodificar en modo de 8 bits una cadena codificada esperando ser decodificada como valores posibles de más de 8 bits, obtenemos los valores crudos, de bajo nivel, de la secuencia de caracteres, listos para ser enviados de forma portable o para ser codificados sin error con las funciones de Base64.

function StringToBytes(str)
{
 try{
  //Convertir a secuencia de escape
  //de URI con valores de 8 bits:
  ///
    str=encodeURIComponent(str);

  //Decodificar la secuencia de
  //escape URI, en modo de 8 bits
  //para obtener cada uno de los bytes
  //crudos de la cadena, en lugar de
  //caracteres individuales pero
  //potencialmente multibytes:
  ///
   str=unescape(str);
 }catch(e){}

 return str;
}

NOTA: Aun cuando en memoria el contenido de la cadena de bajo nivel es binario perfecto con 8 bits efectivos por carácter, si por ejemplo lo escribimos como el valor de un textarea o un campo de texto cualquiera, y lo copiamos y luego lo pegamos manualmente, habremos efectivamente destruído el contenido binario integral de la cadena de bajo nivel. Así que por regla general, este tipo de cadenas solamente puede transmitirse mediante JavaScript, de su memoria hacia la red o un archivo, o a otra variable, etc., pero nunca copiando y pegando manualmente, y preferiblemente no enviar a campos de formulario de usuario y luego pretender recuperar el valor intacto a partir de estos.


[Volver al Índice de Este Documento]
[Volver al Índice del Sitio]