Control protocolo TCP-IP y la codificación de caracteres


([N3] pacosatu) #1

Hola.

Estoy montando una aplicación y uso el control protocolo TCP-IP de Velneo.
Velneo actúa de cliente y el servidor de sockets es una aplicación externa.

¿Cómo hacéis para codificar/decodificar strings UNICODE o UTF-8? No encuentro una manera directa y rápida de que funcione.

Si probáis el Tutor TCP-IP veréis que el caracter del Euro € no funciona, aun siendo cliente y servidor de Velneo.

Necesitamos algo como las funciones: StringToBinary(string, codec) y BinaryToString(binary, codec)

Saludos
Paco Satué


([N4] bitcodesoft) #2

Las cadenas las tienes que codificar en javaScript de la siguiente forma:

escape( cadena_campo_variable_etc )

y para decodificar:

unescape( cadena_campo_variable_etc )


([N3] pacosatu) #3

Hola bitcodesoft.

Vaya, ya me había olvidado de este hilo. Gracias por el interés.
La verdad es que fue un chasco comprobar cómo el control TCP-IP de Velneo no tenía una solución de alto nivel para la codificación/decodificación de cadenas de texto UNICODE.

Ya conocía la función escape, aunque ahora se sustituye por encodeURIComponent().

Quería hacerlo todo con Velneo e independizarlo de javascript y con codificación simple a Latin1 y con opción de codificar también a Hexadecimal.

Este fue el resultado:

FUN_UTI_ENCODE_UTF8. Codifica una cadena UTF-8 con opción Hexadecimal


Rem ( Convierte el String Unicode en otro string de caracteres de un solo byte codificado en UTF-8 )
Rem ( Expresamos el string Unicode con caracteres de 1 byte (FF) )
Rem ( De esta forma es más sencillo realizar otras codificaciones al string )
Rem ( La codificación UTF-8 usa de 1 a 4 bytes para representar todos los caracteres Unicode )
Rem ( Aquí contemplamos hasta caracteres de 3 bytes, aunque la mayoría usan 1 o 2 bytes )
Rem ( Por ejemplo: El caracter del euro € se codifica en UTF-8 con 3 bytes --> € (0xE282AC) )
Rem ( En Velneo se hace con la función --> stringToAscii("€", "UTF-8") )
Libre
Rem ( Parámetros: CTEXTO. Texto a Codificar )
Rem (             LHEXADECIMAL. Es 1 para devolver la cadena codificada también en Hexadecimal )
Libre
If ( LHEXADECIMAL )
   Set ( CRESULTADO, stringToHex(stringToAscii(CTEXTO, "UTF-8")) )
Else
   Set ( CRESULTADO, stringToAscii(CTEXTO, "UTF-8") )
Set dato de retorno ( CRESULTADO )

FUN_UTI_DECODE_UTF8. Decodifica una cadena de caracteres Latin1 con opción Hexadecimal a UTF-8
No he visto que Velneo tenga una función nativa, así que toca hacerlo a pelo.


Rem ( Recibimos un String de caracteres Latin1 (bytes) que representan una cadena codificada UTF-8 )
Rem ( En UTF-8 cada caracter puede ir codificado usando de 1 a 3 bytes )
Rem ( Recorremos el String caracter a caracter )
Libre
Rem ( Parámetros: CTEXTO. Texto a Decodificar )
Rem (             LHEXADECIMAL. Es 1 cuando la cadena está codificada también en Hexadecimal )
Libre
If ( LHEXADECIMAL )
   Set ( CCADENA_HEX, CTEXTO )
   Set ( CTEXTO, "" )
   Rem ( Recibe un String HEXADECIMAL que representa una String codificado en UTF8 )
   Rem ( Primero pasamos el String HEX a un String de caracteres )
   For ( NCAR, 0, NCAR < len(CCADENA_HEX), 2 )
      Rem ( Cada 2 bytes representan un caracter de la codificación UTF-8 )
      Rem ( Por ejemplo: el euro € es 0xE282AC --> € )
      Set ( CTEXTO, CTEXTO + getUnicodeChar(stringHexToNumber(mid(CCADENA_HEX, NCAR, 2))))
Libre
For ( NCAR, 0, NCAR < len(CTEXTO), 1 )
   Set ( CCAR, mid(CTEXTO, NCAR, 1) )
   Set ( NCODE, getLatin1CharCode(CCAR) )
   Rem ( El código Latin1 puede valer de 1 a 255 (un byte) )
   Rem ( El valor del primer Byte determina si el grupo UTF-8 es de 1, 2 o 3 bytes )
   If ( NCODE < 128 )
      Rem ( Obtenemos el caracter UNICODE codificado en 1 byte )
      Set ( CRESULTADO, CRESULTADO + getUnicodeChar(NCODE) )
   Else if ( (NCODE > 191) & (NCODE < 224) )
      Set ( CCAR1, mid(CTEXTO, NCAR+ 1, 1) )
      Set ( NCODE1, getLatin1CharCode(CCAR1) )
      Set ( NOPER1, stringBinToNumber((numberToStringBin(binaryAND(NCODE, 31)) + fillString("0",6))) )
      Set ( NOPER2, binaryAND(NCODE1, 63) )
      Rem ( Obtenemos el caracter UNICODE codificado en 2 bytes )
      Set ( CRESULTADO, CRESULTADO + getUnicodeChar(binaryOR(NOPER1, NOPER2)) )
      Set ( NCAR, NCAR + 1 )
   Else
      Set ( CCAR1, mid(CTEXTO, NCAR+ 1, 1) )
      Set ( CCAR2, mid(CTEXTO, NCAR+ 2, 1) )
      Set ( NCODE1, getLatin1CharCode(CCAR1) )
      Set ( NCODE2, getLatin1CharCode(CCAR2) )
      Set ( NOPER1, stringBinToNumber((numberToStringBin(binaryAND(NCODE, 15)) + fillString("0",12))) )
      Set ( NOPER2, stringBinToNumber((numberToStringBin(binaryAND(NCODE1, 63)) + fillString("0", 6))) )
      Set ( NOPER3, binaryAND(NCODE2, 63) )
      Rem ( Obtenemos el caracter UNICODE codificado en 3 bytes )
      Set ( CRESULTADO, CRESULTADO + getUnicodeChar(binaryOR(NOPER1, binaryOR(NOPER2, NOPER3))) )
      Set ( NCAR, NCAR + 2 )
      Libre
Rem ( El resultado contiene los caracteres UNICODE )
Set dato de retorno ( CRESULTADO )

Ahora ya podemos enviar cadenas UNICODE a través del control TCP-IP de Velneo (Ver el Tutor).

Saludos
Paco Satué


([N4] Infortic) #4

Como siempre gracias por tu aportación Paco.