[英]Encoding and decoding byte[] with ZXing
我正在開發一個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,每個人都聲稱是這類問題的解決方案( 其他主題處理相同類型的問題或在這里 ),我不知道看看我的錯誤在哪里,或者我是否在編碼或解碼過程中跳過了一步。 這是我執行以編碼給定字節數組的代碼:
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();
為了解碼QRCode,我發送以下Intent
@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);
}
並等待結果:
@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
}
}
}
你能告訴我我的錯誤在哪里,或者我應該在哪里看?
非常感謝,
弗蘭克
在我的一個應用程序中,我需要對使用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");
...
}
我認為在開始掃描的意圖數據中沒有將CHARACTER_SET設置為ISO-8859-1是使原始問題的代碼失敗的點。 我花了很長時間才把它挖出來,因為我沒有看到這個明顯張貼在任何地方,拉丁文1編碼是Xzing中QR碼的標准編碼。 特別棘手的是,Xzing在線解碼器http://zxing.org/w/decode.jspx也沒有設置CHARACTER_SET,因此生成的QR碼在此站點上解碼時看起來有問題。
您錯誤地認為可以將任意二進制數據轉換為有效字符串而不使用某種鎧裝。 它不起作用。 Binary - > text - > binary使用任何標准字符集/編碼都是有損的。 (提示:使用UTF-8也不起作用。)
您應該使用類似base64編碼或十六進制編碼的方法來確保二進制數據不會被破壞。
從概念上講,QR碼編碼文本而不是字節。 當然,他們將輸入轉換為一系列字節,盡管這對調用者來說是不透明的。 你是對的,正如它發生的那樣,選擇正確的編碼會讓你偷偷摸摸通過,而ISO-8859-1是正確的選擇。 實際上它確實有效。
ASCII是不可能的,因為它沒有定義> = 128的字符,而UTF-8肯定不會起作用
這里的問題可能是你的代碼。 我不確定你在這里嘗試了什么......看起來你正准備在某個地方發送一個Intent
(到Barcode Scanner?)但是你沒有,你只是制作一個Intent
並發送給它你從項目中復制了一些代碼? 我想象你如何為Intent
設置額外內容出了問題。
如果你在你的應用程序中這樣做,這應該會簡單得多。 只需直接重用QRCodeEncoder.encodeAsBitmap()
並刪除其余部分。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.