Codificación y decodificación de bytes con ZXing

Estoy desarrollando una aplicación para Android, y necesito codificar y decodificar una matriz de bytes en un QRCode generado con la aplicación ZXing. Mi problema es que mi mensaje decodificado no coincide exactamente con la matriz de bytes generados. Intenté crear un QRCode basado en una matriz de bytes que contenga índices de incremento, es decir

input = [0, 1, 2, ..., 124, 125, 126, 127, -128, -127,... -3, -2, -1, 0, 1, 2, ...] 

Y después de codificar el mensaje en el QRCode y decodificarlo en el lado del respondedor, obtengo la siguiente salida del array de bytes:

 output = [0, 1, 2, ..., 124, 125, 126, 127, 63, 63,... 63, 63, 63, 0, 1, 2, ...] 

Todos los valores de bytes "negativos" se convierten en ASCII char 63: '?' Signos de interrogación. Supongo que algo está saliendo mal con el charset de codificación, pero como estoy utilizando ISO-8859-1, que todo el mundo afirma ser la solución de este tipo de problema ( otro tema que trata el mismo tipo de problema o aquí ) T ver dónde está mi error, o si estoy saltando un paso durante la instanciation de la codificación o la decodificación. Aquí está el código que ejecuto para codificar una matriz de bytes dada:

 String text = ""; byte[] res = new byte[272]; for (int i = 0; i < res.length; i++) { res[i] = (byte) (i%256); } try { text = new String(res, "ISO8859_1"); } catch (UnsupportedEncodingException e) { // TODO } Intent intent = new Intent(Intents.Encode.ACTION); Intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET); intent.putExtra(Intents.Encode.TYPE, Contents.Type.TEXT); intent.putExtra(Intents.Encode.FORMAT, "ISO8859_1"); intent.putExtra(Intents.Encode.DATA, text); intent.putExtra(Intents.Encode.FORMAT, BarcodeFormat.QR_CODE.toString()); boolean useVCard = intent.getBooleanExtra(USE_VCARD_KEY, false); QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(activity, intent, dimension, useVCard); Bitmap bitmap = qrCodeEncoder.encodeAsBitmap(); 

Y para decodificar un QRCode, envío la siguiente Intención

 @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.qrcodeDecoding); Intent intent = new Intent(Intents.Scan.ACTION); intent.putExtra(Intents.Scan.MODE, Intents.Scan.QR_CODE_MODE); startActivityForResult(intent, 0); } 

Y esperar a Resultado:

 @Override protected void onActivityResult(int request, int result, Intent data) { if(request == 0) { //action if(result == RESULT_OK) { String res = data.getStringExtra(Intents.Scan.RESULT); byte[] dat = null; try{ dat = res.getBytes("ISO8859_1"); } catch(UnsopportedEncodingException e) { //TODO } } else if(result == RESULT_CANCELED) { //TODO } } } 

¿Podría decirme por favor dónde están mis errores, o dónde debo mirar?

Muchas gracias,

Franck

Estás cometiendo el error de pensar que puedes convertir datos binarios arbitrarios en una cadena válida sin usar algún tipo de armadura. No funciona. Binario -> texto -> binario se pierde utilizando cualquiera de los conjuntos de caracteres estándar / codificación. (Sugerencia: el uso de UTF-8 tampoco funcionará).

Debe utilizar algo como la codificación de base64 o la codificación hexadecimal para garantizar que los datos binarios no se mutilen.

En una de mis aplicaciones necesitaba codificar y decodificar una matriz de bytes en un QRCode generado con la aplicación ZXing. Como la matriz de bytes contenía datos de texto comprimido que quería evitar la codificación base64. Es posible hacerlo, pero como no he visto hasta ahora un conjunto completo de fragmentos de código, los publicaré aquí.

Codificación:

 public void showQRCode(Activity activity, byte[] data){ Intent intent = new Intent("com.google.zxing.client.android.ENCODE"); intent.putExtra("ENCODE_TYPE", "TEXT_TYPE"); intent.putExtra("ENCODE_SHOW_CONTENTS", false); intent.putExtra("ENCODE_DATA", new String(data, "ISO-8859-1")); activity.startActivity(intent); } 

Iniciar la exploración:

 public static void startQRCodeScan(Activity activity){ Intent intent = new Intent(com.google.zxing.client.android.SCAN); intent.putExtra("SCAN_MODE", "QR_CODE_MODE"); intent.putExtra("CHARACTER_SET", "ISO-8859-1"); activity.startActivityForResult(intent, 0); } 

Controlador de resultados de escaneado:

 public void onActivityResult(int requestCode, int resultCode, Intent intent) { byte[] result = intent.getStringExtra("SCAN_RESULT").getBytes("ISO-8859-1"); ... } 

Creo que no establecer CHARACTER_SET a ISO-8859-1 en los datos de intención para iniciar el análisis es el punto que hizo que el código de la pregunta original no. Me tomó bastante tiempo para cavar esto como no he visto esto claramente publicado en cualquier lugar y la codificación de latín 1 es la codificación estándar para el código QR en Xzing. Especialmente difícil es el hecho de que el descodificador online de Xzing http://zxing.org/w/decode.jspx no establece CHARACTER_SET también para que el código QR generado parezca defectuoso cuando se decodifica en este sitio.

Conceptualmente, los códigos QR codifican el texto, no los bytes. En el interior, por supuesto, traducen la entrada a una serie de bytes, aunque eso es opaco para la persona que llama. Usted tiene razón que, como sucede, la elección de la codificación correcta le permitiría colar los bytes a través, e ISO-8859-1 es la elección correcta aquí. En realidad, funciona.

ASCII no es posible ya que no define chars para> = 128, y UTF-8 definitivamente no va a funcionar

El problema aquí es probablemente su código. No estoy seguro de lo que estás intentando aquí … parece que estás configurando para enviar un Intent algún lugar (a Barcode Scanner?) Pero entonces no lo haces, solo estás haciendo un Intent y enviándolo a Algún código que copió del proyecto? Me imagino que algo ha salido mal con la forma en que se están estableciendo extras para la Intent .

Esto debería ser mucho más simple si lo estás haciendo dentro de tu aplicación. Simplemente reutilice QRCodeEncoder.encodeAsBitmap() directamente y elimine el resto de esto.

  • ¿Puedo usar Zxing para fines comerciales?
  • Agregue el proyecto android de ZXing como biblioteca en android studio
  • Un escáner de QR dentro de un fragmento
  • Android + biblioteca de escaneo de códigos de barras ZXing - tamaño personalizado y orientación
  • Escáner QR con ZXing y ZBar no lee códigos de baja calidad en las tarjetas
  • Zxing usando diseño personalizado
  • Escáner de código de barras ZXing Propósito: set DecodeHintType.ASSUME_GS1
  • Escaneo de códigos de barras / código de barras de ZXing QR
  • Incorporar la biblioteca Zxing sin utilizar la aplicación Scanner de códigos de barras
  • Zxing modo retrato de la cámara y el paisaje en Android
  • Escaneo de códigos QR sin cámara de pantalla completa
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.