Java 使用ZXing对字节[]进行编码和解码

Java 使用ZXing对字节[]进行编码和解码,java,android,character-encoding,zxing,iso-8859-1,Java,Android,Character Encoding,Zxing,Iso 8859 1,我正在开发一个Android应用程序,我需要对ZXing应用程序生成的QRCode中的字节数组进行编码和解码。我的问题是,我解码的消息与生成的字节数组不完全匹配。 我尝试基于包含递增索引的字节数组创建QRCode,即 input = [0, 1, 2, ..., 124, 125, 126, 127, -128, -127,... -3, -2, -1, 0, 1, 2, ...] 在QRCode中对消息进行编码并在响应端对其进行解码后,我获得以下字节数组输出: output = [0, 1,

我正在开发一个Android应用程序,我需要对ZXing应用程序生成的QRCode中的字节数组进行编码和解码。我的问题是,我解码的消息与生成的字节数组不完全匹配。 我尝试基于包含递增索引的字节数组创建QRCode,即

input = [0, 1, 2, ..., 124, 125, 126, 127, -128, -127,... -3, -2, -1, 0, 1, 2, ...]
在QRCode中对消息进行编码并在响应端对其进行解码后,我获得以下字节数组输出:

output = [0, 1, 2, ..., 124, 125, 126, 127, 63, 63,... 63, 63, 63, 0, 1, 2, ...]
所有“负”字节值都转换为ASCII字符63:“?”问号字符。 我假设编码字符集出了问题,但由于我使用的是ISO-8859-1,每个人都声称它是此类问题的解决方案(or),我不知道我的错误在哪里,或者我是否在编码或解码的实例化过程中跳过了一步。 以下是我为编码给定字节数组而执行的代码:

String text=”“;
字节[]res=新字节[272];
for(int i=0;i
为了解码QR码,我发送以下信息

@覆盖
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.qrcodeDecoding);
意向意向=新意向(意向.扫描.动作);
intent.putExtra(intent.Scan.MODE,intent.Scan.QR\u码\u模式);
startActivityForResult(意向,0);
}
并等待结果:

@覆盖
受保护的void onActivityResult(int请求、int结果、意图数据)
{
如果(请求==0)
{
//行动
如果(结果==结果\确定)
{
String res=data.getStringExtra(Intents.Scan.RESULT);
字节[]dat=null;
试一试{
dat=res.getBytes(“ISO8859_1”);
}捕获(未经支持的编码异常e){
//待办事项
}
}
else if(结果==结果_已取消)
{
//待办事项
}
}
}
你能告诉我哪里是我的错误,或者我应该看哪里吗

多谢各位


Franck

您错误地认为可以将任意二进制数据转换为有效字符串,而无需使用某种防护。它不起作用。二进制->文本->二进制使用任何标准字符集/编码都是有损的。(提示:使用UTF-8也不起作用。)


您应该使用base64编码或十六进制编码来确保二进制数据不会被破坏。

从概念上讲,QR码编码的是文本,而不是字节。当然,它们在内部将输入转换为一系列字节,尽管这对调用者来说是不透明的。您是对的,选择正确的编码会让您偷偷地通过字节,而ISO-8859-1是正确的选择。事实上,它确实有效

ASCII是不可能的,因为它没有为>=128定义字符,而且UTF-8肯定不起作用

这里的问题可能是您的代码。我不知道你在尝试什么。。。看起来您正在设置将
意图
发送到某个地方(到条形码扫描仪?),但是您没有,您只是在制作
意图
并将其发送到从项目复制的某个代码?我想您在设置
意图的额外功能时出了问题


如果您在应用程序中执行此操作,则应该简单得多。只需直接重用
QRCodeEncoder.encodeAsBitmap()
,并删除其余部分。

在我的一个应用程序中,我需要对ZXing应用程序生成的QRCode中的字节数组进行编码和解码。由于字节数组包含压缩文本数据,我希望避免base64编码。这样做是可能的,但由于我到目前为止还没有看到完整的代码片段集,我将在这里发布它们

编码:

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);
}
开始扫描:

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);
}
扫描结果处理程序:

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

我认为在开始扫描的意图数据中没有将字符设置为ISO-8859-1是导致原始问题代码失败的原因。我花了相当长的时间才弄明白这一点,因为我还没有在任何地方清楚地看到这一点,拉丁1编码是Xzing中QR码的标准编码。尤其棘手的是,Xzing在线解码器没有设置字符集,因此在本网站解码时生成的QR码看起来有问题。

只是为了“玩转”(我不知道这一点)例如,如果使用UTF-8作为编码,会发生什么?UTF-8肯定不起作用。首先,并非每个字节序列都是有效的UTF-8序列。因此,用这种方式从大多数输入中提取字符串是不可能的;ISO-8559-1在Java中正好可以用于此目的。@StephenC非常感谢,在我的实现中使用base64编码解决了这个问题@SeanOwen我同意你的观点,将字节[]编码和解码为字符串ISO-8859-1,反之亦然。问题可能位于ZXing层上。然而,base64解决了这个问题。据我所知,将任意缓冲区转换为字符串时,ISO-8859-1的效率是100%。base64为75%。我的理解错了吗?@LucaCarlon-不,不是。但是效率并不是唯一的问题。
QRCodeEncoder
的唯一构造函数接受参数
QRCodeEncoder(活动、意图、目的)