fix: decode base64-encoded file content

This commit is contained in:
2026-05-27 12:21:39 -05:00
parent 0c94421337
commit 553319ea68
@@ -1,54 +1,177 @@
cGFja2FnZSBhbmRyb2lkLnNlcmlhbHBvcnQudXRpbHM7CgppbXBvcnQgYW5kcm9pZC5vcy5IYW5k package android.serialport.utils;
bGVyOwppbXBvcnQgYW5kcm9pZC5vcy5NZXNzYWdlOwppbXBvcnQgYW5kcm9pZC51dGlsLkxvZzsK
CmltcG9ydCBhbmRyb2lkeC5hbm5vdGF0aW9uLk5vbk51bGw7CgppbXBvcnQgamF2YS5pby5GaWxl import android.os.Handler;
OwppbXBvcnQgamF2YS5pby5GaWxlSW5wdXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLkZpbGVPdXRw import android.os.Message;
dXRTdHJlYW07CmltcG9ydCBqYXZhLmlvLkZpbGVXcml0ZXI7CmltcG9ydCBqYXZhLmlvLklPRXhj import android.util.Log;
ZXB0aW9uOwppbXBvcnQgamF2YS51dGlsLkFycmF5TGlzdDsKaW1wb3J0IGphdmEudXRpbC5jb25j
dXJyZW50LkxpbmtlZEJsb2NraW5nUXVldWU7CgpwdWJsaWMgY2xhc3MgQnl0ZVV0aWwgewogICAg import androidx.annotation.NonNull;
cHJpdmF0ZSBzdGF0aWMgY2hhcltdIGhleEFycmF5ID0gIjAxMjM0NTY3ODlBQkNERUYiLnRvQ2hh
ckFycmF5KCk7CiAgICAvL0RlZmF1bHQgYnl0ZQogICAgLyoqCiAgICAgKiDlrZfnrKbkuLLovazl import java.io.File;
rZfoioLmlbDnu4QKICAgICAqCiAgICAgKiBAcGFyYW0gcyDlrZfnrKbkuLIKICAgICAqIEByZXR1 import java.io.FileInputStream;
cm4g5pWw57uECiAgICAgKi8KICAgIHB1YmxpYyBzdGF0aWMgYnl0ZVtdIGhleFN0cmluZ1RvQnl0 import java.io.FileOutputStream;
ZUFycmF5KFN0cmluZyBzKSB7CiAgICAgICAgaWYgKHMubGVuZ3RoKCkgPCAyKSB7CiAgICAgICAg import java.io.FileWriter;
ICAgIHMgPSAiMCIgKyBzOwogICAgICAgIH0KICAgICAgICBpbnQgbGVuID0gcy5sZW5ndGgoKTsK import java.io.IOException;
ICAgICAgICBieXRlW10gZGF0YSA9IG5ldyBieXRlW2xlbiAvIDJdOwogICAgICAgIGZvciAoaW50 import java.util.ArrayList;
IGkgPSAwOyBpIDwgbGVuOyBpICs9IDIpIHsKICAgICAgICAgICAgZGF0YVtpIC8gMl0gPSAoYnl0 import java.util.concurrent.LinkedBlockingQueue;
ZSkgKChDaGFyYWN0ZXIuZGlnaXQocy5jaGFyQXQoaSksIDE2KSA8PCA0KSArIENoYXJhY3Rlci5k
aWdpdChzLmNoYXJBdChpICsgMSksIDE2KSk7CiAgICAgICAgfQogICAgICAgIHJldHVybiBkYXRh public class ByteUtil {
OwogICAgfQoKICAgIC8qKgogICAgICog5a2X6IqC5pWw57uE6L2s5a2X56ym5LiyCiAgICAgKgog private static char[] hexArray = "0123456789ABCDEF".toCharArray();
ICAgICogQHBhcmFtIGhleEJ5dGVzIOaVsOe7hAogICAgICogQHJldHVybiDlrZfnrKbkuLIKICAg //Default byte
ICAqLwogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgaGV4Qnl0ZXNUb1N0cmluZyhieXRlW10gaGV4 /**
Qnl0ZXMpIHsKICAgICAgICBjaGFyW10gaGV4Q2hhcnMgPSBuZXcgY2hhcltoZXhCeXRlcy5sZW5n * 字符串转字节数组
dGggKiAyXTsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IGhleEJ5dGVzLmxlbmd0aDsgaisr *
KSB7CiAgICAgICAgICAgIGludCB2ID0gaGV4Qnl0ZXNbal0gJiAweEZGOwogICAgICAgICAgICBo * @param s 字符串
ZXhDaGFyc1tqICogMl0gPSBoZXhBcnJheVt2ID4+PiA0XTsKICAgICAgICAgICAgaGV4Q2hhcnNb * @return 数组
aiAqIDIgKyAxXSA9IGhleEFycmF5W3YgJiAweDBGXTsKICAgICAgICB9CiAgICAgICAgcmV0dXJu */
IG5ldyBTdHJpbmcoaGV4Q2hhcnMpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgaW50IGhleFN0 public static byte[] hexStringToByteArray(String s) {
cmluZ1RvSW50KFN0cmluZyBoZXhTdHJpbmcpIHsKICAgICAgICByZXR1cm4gSW50ZWdlci5wYXJz if (s.length() < 2) {
ZUludChoZXhTdHJpbmcsIDE2KTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGJ5dGVbXSBoZXhT s = "0" + s;
dHJpbmdUb0J5dGVzKFN0cmluZyBoZXhTdHJpbmcpIHsKICAgICAgICBpZiAoaGV4U3RyaW5nID09 }
IG51bGwgfHwgaGV4U3RyaW5nLmVxdWFscygiIikpIHsKICAgICAgICAgICAgcmV0dXJuIG51bGw7 int len = s.length();
CiAgICAgICAgfQogICAgICAgIGhleFN0cmluZyA9IGhleFN0cmluZy50b1VwcGVyQ2FzZSgpOwog byte[] data = new byte[len / 2];
ICAgICAgIGludCBsZW5ndGggPSBoZXhTdHJpbmcubGVuZ3RoKCkgLyAyOwogICAgICAgIGNoYXJb for (int i = 0; i < len; i += 2) {
XSBoZXhDaGFycyA9IGhleFN0cmluZy50b0NoYXJBcnJheSgpOwogICAgICAgIGJ5dGVbXSBkID0g data[i / 2] = (byte) ((Character.digit(s.charAt(i), 16) << 4) + Character.digit(s.charAt(i + 1), 16));
bmV3IGJ5dGVbbGVuZ3RoXTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IGxlbmd0aDsgaSsr }
KSB7CiAgICAgICAgICAgIGludCBwb3MgPSBpICogMjsKICAgICAgICAgICAgZFtpXSA9IChieXRl return data;
KSAoY2hhclRvQnl0ZShoZXhDaGFyc1twb3NdKSA8PCA0IHwgY2hhclRvQnl0ZShoZXhDaGFyc1tw }
b3MgKyAxXSkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gZDsKICAgIH0KCiAgICBwdWJsaWMg
c3RhdGljIGJ5dGUgY2hhclRvQnl0ZShjaGFyIGMpIHsKICAgICAgICByZXR1cm4gKGJ5dGUpICIw /**
MTIzNDU2Nzg5QUJDREVGIi5pbmRleE9mKGMpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgYnl0 * 字节数组转字符串
ZVtdIGludFRvQnl0ZUFycmF5KGludCBhKSB7CiAgICAgICAgYnl0ZVtdIHJldCA9IG5ldyBieXRl *
WzRdOwogICAgICAgIHJldFszXSA9IChieXRlKSAoYSAmIDB4RkYpOwogICAgICAgIHJldFsyXSA9 * @param hexBytes 数组
IChieXRlKSAoKGEgPj4gOCkgJiAweEZGKTsKICAgICAgICByZXRbMV0gPSAoYnl0ZSkgKChhID4+ * @return 字符串
IDE2KSAmIDB4RkYpOwogICAgICAgIHJldFswXSA9IChieXRlKSAoKGEgPj4gMjQpICYgMHhGRik7 */
CiAgICAgICAgcmV0dXJuIHJldDsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyB0b0hl public static String hexBytesToString(byte[] hexBytes) {
eChieXRlW10gYnl0ZXMsIGludCBvZmZzZXQsIGludCBsZW5ndGgpIHsKICAgICAgICBjaGFyW10g char[] hexChars = new char[hexBytes.length * 2];
aGV4Q2hhcnMgPSBuZXcgY2hhcltsZW5ndGggKiAyXTsKICAgICAgICBTdHJpbmdCdWlsZGVyIHN0 for (int j = 0; j < hexBytes.length; j++) {
cmluZ0J1aWxkZXIgPSBuZXcgU3RyaW5nQnVpbGRlcigpOwogICAgICAgIGZvciAoaW50IGogPSBv int v = hexBytes[j] & 0xFF;
ZmZzZXQ7IGogPCBsZW5ndGggKyBvZmZzZXQ7IGorKykgewogICAgICAgICAgICBpbnQgdiA9IGJ5 hexChars[j * 2] = hexArray[v >>> 4];
dGVzW2pdICYgMHhGRjsKICAgICAgICAgICAgaGV4Q2hhcnNbKGogLSBvZmZzZXQpICogMl0gPSBo hexChars[j * 2 + 1] = hexArray[v & 0x0F];
ZXhBcnJheVt2ID4+PiA0XTsKICAgICAgICAgICAgaGV4Q2hhcnNbKGogLSBvZmZzZXQpICogMiAr }
IDFdID0gaGV4QXJyYXlbdiAmIDB4MEZdOwogICAgICAgICAgICBzdHJpbmdCdWlsZGVyLmFwcGVu return new String(hexChars);
ZChoZXhBcnJheVt2ID4+PiA0XSk7CiAgICAgICAgICAgIHN0cmluZ0J1aWxkZXIuYXBwZW5kKGhl }
eEFycmF5W3YgJiAweDBGXSk7CiAgICAgICAgICAgIHN0cmluZ0J1aWxkZXIuYXBwZW5kKCJcdCIp
OwogICAgICAgIH0KICAgICAgICByZXR1cm4gbmV3IFN0cmluZyhoZXhDaGFycyk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgdG9IZXgoYnl0ZVtdIGJ5dGVzKSB7CiAgICAgICAgcmV0dXJuIHRvSGV4KGJ5dGVzLCAwLCBieXRlcy5sZW5ndGgpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgU3RyaW5nIHRvSGV4KGludCBhQnl0ZSkgewogICAgICAgIHJldHVybiBTdHJpbmcuZm9ybWF0KCIweCUwMlgiLCBhQnl0ZSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgYnl0ZXNUb0hleFdpdGhTcGFjZShieXRlW10gYnl0ZXMpIHsKICAgICAgICBTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoKTsKICAgICAgICBmb3IgKGJ5dGUgYiA6IGJ5dGVzKSB7IHNiLmFwcGVuZChTdHJpbmcuZm9ybWF0KCIlMDJYIiwgYikpOyB9CiAgICAgICAgcmV0dXJuIHNiLnRvU3RyaW5nKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBTdHJpbmcgYnl0ZXNUb0hleFdpdGhTcGFjZShieXRlIGIpIHsKICAgICAgICByZXR1cm4gU3RyaW5nLmZvcm1hdCgiJTAyWCAiLCBiKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIFN0cmluZyBieXRlc1RvSGV4V2l0aE5ld0xpbmUoYnl0ZVtdIGJ5dGVzKSB7CiAgICAgICAgU3RyaW5nQnVpbGRlciBzYiA9IG5ldyBTdHJpbmdCdWlsZGVyKCk7CiAgICAgICAgZm9yIChieXRlIGIgOiBieXRlcykgeyBzYi5hcHBlbmQoU3RyaW5nLmZvcm1hdCgiJTAyWCIsIGIpKS5hcHBlbmQoIlxuIik7IH0KICAgICAgICByZXR1cm4gc2IudG9TdHJpbmcoKTsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIGJ5dGUgdG9CeXRlKEludGVnZXIgYnl0ZUludGVnZXIsIGludCBkZWZhdWx0Qnl0ZSkgewogICAgICAgIHJldHVybiBieXRlSW50ZWdlciA9PSBudWxsID8gKGJ5dGUpIGRlZmF1bHRCeXRlIDogYnl0ZUludGVnZXIuYnl0ZVZhbHVlKCk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBieXRlIHRvQnl0ZShTdHJpbmcgZmlsZU5hbWUsIGludCBkZWZhdWx0Qnl0ZSkgewogICAgICAgIGlmIChmaWxlTmFtZS5pc0VtcHR5KCkpIHsgcmV0dXJuIChieXRlKSBkZWZhdWx0Qnl0ZTsgfQogICAgICAgIHJldHVybiBCeXRlLnBhcnNlQnl0ZShmaWxlTmFtZSk7CiAgICB9CgogICAgcHVibGljIHN0YXRpYyBBcnJheUxpc3Q8QXJyYXlMaXN0PFN0cmluZz4+IGNhY2hlUmVzdWx0ID0gbmV3IEFycmF5TGlzdDw+KCk7CiAgICBwdWJsaWMgc3RhdGljIFN0cmluZ0J1ZmZlciByZWFkUiA9IG5ldyBTdHJpbmdCdWZmZXIoKTsKICAgIHB1YmxpYyBzdGF0aWMgTGlua2VkQmxvY2tpbmdRdWV1ZTxBcnJheUxpc3Q8U3RyaW5nPj4gdW5ib3VuZGVkUXVldWUgPSBuZXcgTGlua2VkQmxvY2tpbmdRdWV1ZTw+KCk7CgogICAgcHVibGljIHN0YXRpYyB2b2lkIHJlYWRCaW5hcnlGaWxlKFN0cmluZyBmaWxlUGF0aCkgewogICAgICAgIHJlYWRSID0gbmV3IFN0cmluZ0J1ZmZlcigpOwogICAgICAgIGNhY2hlUmVzdWx0LmNsZWFyKCk7CiAgICAgICAgdW5ib3VuZGVkUXVldWUuY2xlYXIoKTsKICAgICAgICB0cnkgewogICAgICAgICAgICBGaWxlIGZpbGUgPSBuZXcgRmlsZShmaWxlUGF0aCk7CiAgICAgICAgICAgIEZpbGVJbnB1dFN0cmVhbSBmaXMgPSBuZXcgRmlsZUlucHV0U3RyZWFtKGZpbGUpOwogICAgICAgICAgICBsb25nIGxlbmd0aCA9IGZpbGUubGVuZ3RoKCk7CiAgICAgICAgICAgIGJ5dGVbXSBieXRlcyA9IG5ldyBieXRlWyhpbnQpIGxlbmd0aF07CiAgICAgICAgICAgIGZpcy5yZWFkKGJ5dGVzKTsKICAgICAgICAgICAgZmlzLmNsb3NlKCk7CiAgICAgICAgICAgIGludCBwYXJ0U2l6ZSA9IGJ5dGVzLmxlbmd0aCAvIDEwMjQgLSAxOwogICAgICAgICAgICBpbnQgdG90YWxTaXplID0gMDsKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBwYXJ0U2l6ZTsgaSsrKSB7CiAgICAgICAgICAgICAgICBieXRlW10gbmV3QXJyYXkgPSBuZXcgYnl0ZVsxMDI0XTsKICAgICAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnl0ZXMsIGkgKiAxMDI0LCBuZXdBcnJheSwgMCwgMTAyNCk7CiAgICAgICAgICAgICAgICBBcnJheUxpc3Q8U3RyaW5nPiB0ZW0gPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICAgICAgICAgIGZvciAoYnl0ZSBiIDogbmV3QXJyYXkpIHsgdGVtLmFkZChTdHJpbmcuZm9ybWF0KCIlMDJYIiwgYikpOyB9CiAgICAgICAgICAgICAgICBjYWNoZVJlc3VsdC5hZGQodGVtKTsKICAgICAgICAgICAgICAgIHVuYm91bmRlZFF1ZXVlLmFkZCh0ZW0pOwogICAgICAgICAgICAgICAgdG90YWxTaXplICs9IG5ld0FycmF5Lmxlbmd0aDsKICAgICAgICAgICAgfQogICAgICAgICAgICBieXRlW10gbGFzdEFycmF5ID0gbmV3IGJ5dGVbMTAyNF07CiAgICAgICAgICAgIFN5c3RlbS5hcnJheWNvcHkoYnl0ZXMsIHBhcnRTaXplICogMTAyNCwgbGFzdEFycmF5LCAwLCBieXRlcy5sZW5ndGggLSBwYXJ0U2l6ZSAqIDEwMjQpOwogICAgICAgICAgICBBcnJheUxpc3Q8U3RyaW5nPiB0ZW0gPSBuZXcgQXJyYXlMaXN0PD4oKTsKICAgICAgICAgICAgZm9yIChieXRlIGIgOiBsYXN0QXJyYXkpIHsgdGVtLmFkZChTdHJpbmcuZm9ybWF0KCIlMDJYIiwgYikpOyB9CiAgICAgICAgICAgIGNhY2hlUmVzdWx0LmFkZCh0ZW0pOwogICAgICAgICAgICB1bmJvdW5kZWRRdWV1ZS5hZGQodGVtKTsKICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgIGUucHJpbnRTdGFja1RyYWNlKCk7CiAgICAgICAgfQogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCB3cml0ZVN0cmluZ1RvRmlsZShieXRlW10gY29udGVudCwgU3RyaW5nIGZpbGVQYXRoKSB7CiAgICAgICAgdHJ5IChGaWxlT3V0cHV0U3RyZWFtIGZvcyA9IG5ldyBGaWxlT3V0cHV0U3RyZWFtKGZpbGVQYXRoKSkgewogICAgICAgICAgICBmb3Mud3JpdGUoY29udGVudCk7CiAgICAgICAgfSBjYXRjaCAoSU9FeGNlcHRpb24gZSkgewogICAgICAgICAgICBlLnByaW50U3RhY2tUcmFjZSgpOwogICAgICAgIH0KICAgIH0KfQo= public static int hexStringToInt(String hexString) {
return Integer.parseInt(hexString, 16);
}
public static byte[] hexStringToBytes(String hexString) {
if (hexString == null || hexString.equals("")) {
return null;
}
hexString = hexString.toUpperCase();
int length = hexString.length() / 2;
char[] hexChars = hexString.toCharArray();
byte[] d = new byte[length];
for (int i = 0; i < length; i++) {
int pos = i * 2;
d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
}
return d;
}
public static byte charToByte(char c) {
return (byte) "0123456789ABCDEF".indexOf(c);
}
public static byte[] intToByteArray(int a) {
byte[] ret = new byte[4];
ret[3] = (byte) (a & 0xFF);
ret[2] = (byte) ((a >> 8) & 0xFF);
ret[1] = (byte) ((a >> 16) & 0xFF);
ret[0] = (byte) ((a >> 24) & 0xFF);
return ret;
}
public static String toHex(byte[] bytes, int offset, int length) {
char[] hexChars = new char[length * 2];
StringBuilder stringBuilder = new StringBuilder();
for (int j = offset; j < length + offset; j++) {
int v = bytes[j] & 0xFF;
hexChars[(j - offset) * 2] = hexArray[v >>> 4];
hexChars[(j - offset) * 2 + 1] = hexArray[v & 0x0F];
stringBuilder.append(hexArray[v >>> 4]);
stringBuilder.append(hexArray[v & 0x0F]);
stringBuilder.append("\t");
}
return new String(hexChars);
}
public static String toHex(byte[] bytes) {
return toHex(bytes, 0, bytes.length);
}
public static String toHex(int aByte) {
return String.format("0x%02X", aByte);
}
public static String bytesToHexWithSpace(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) { sb.append(String.format("%02X", b)); }
return sb.toString();
}
public static String bytesToHexWithSpace(byte b) {
return String.format("%02X ", b);
}
public static String bytesToHexWithNewLine(byte[] bytes) {
StringBuilder sb = new StringBuilder();
for (byte b : bytes) { sb.append(String.format("%02X", b)).append("\n"); }
return sb.toString();
}
public static byte toByte(Integer byteInteger, int defaultByte) {
return byteInteger == null ? (byte) defaultByte : byteInteger.byteValue();
}
public static byte toByte(String fileName, int defaultByte) {
if (fileName.isEmpty()) { return (byte) defaultByte; }
return Byte.parseByte(fileName);
}
public static ArrayList<ArrayList<String>> cacheResult = new ArrayList<>();
public static StringBuffer readR = new StringBuffer();
public static LinkedBlockingQueue<ArrayList<String>> unboundedQueue = new LinkedBlockingQueue<>();
public static void readBinaryFile(String filePath) {
readR = new StringBuffer();
cacheResult.clear();
unboundedQueue.clear();
try {
File file = new File(filePath);
FileInputStream fis = new FileInputStream(file);
long length = file.length();
byte[] bytes = new byte[(int) length];
fis.read(bytes);
fis.close();
int partSize = bytes.length / 1024 - 1;
int totalSize = 0;
for (int i = 0; i < partSize; i++) {
byte[] newArray = new byte[1024];
System.arraycopy(bytes, i * 1024, newArray, 0, 1024);
ArrayList<String> tem = new ArrayList<>();
for (byte b : newArray) { tem.add(String.format("%02X", b)); }
cacheResult.add(tem);
unboundedQueue.add(tem);
totalSize += newArray.length;
}
byte[] lastArray = new byte[1024];
System.arraycopy(bytes, partSize * 1024, lastArray, 0, bytes.length - partSize * 1024);
ArrayList<String> tem = new ArrayList<>();
for (byte b : lastArray) { tem.add(String.format("%02X", b)); }
cacheResult.add(tem);
unboundedQueue.add(tem);
} catch (IOException e) {
e.printStackTrace();
}
}
public static void writeStringToFile(byte[] content, String filePath) {
try (FileOutputStream fos = new FileOutputStream(filePath)) {
fos.write(content);
} catch (IOException e) {
e.printStackTrace();
}
}
}