diff --git a/electron/idcard-worker.js b/electron/idcard-worker.js index 14513ec..5eea793 100644 --- a/electron/idcard-worker.js +++ b/electron/idcard-worker.js @@ -5,35 +5,49 @@ const iconv = require("iconv-lite"); // 定义结构体 const IDCardData = koffi.struct("IDCardData", { - Name: koffi.array("char", 32), - Sex: koffi.array("char", 6), - Nation: koffi.array("char", 20), - Born: koffi.array("char", 18), - Address: koffi.array("char", 72), - IDCardNo: koffi.array("char", 38), - GrantDept: koffi.array("char", 32), - UserLifeBegin: koffi.array("char", 18), - UserLifeEnd: koffi.array("char", 18), - reserved: koffi.array("char", 38), - PhotoFileName: koffi.array("char", 255), + Name: koffi.array("uint8", 32), + Sex: koffi.array("uint8", 6), + Nation: koffi.array("uint8", 20), + Born: koffi.array("uint8", 18), + Address: koffi.array("uint8", 72), + IDCardNo: koffi.array("uint8", 38), + GrantDept: koffi.array("uint8", 32), + UserLifeBegin: koffi.array("uint8", 18), + UserLifeEnd: koffi.array("uint8", 18), + reserved: koffi.array("uint8", 38), + PhotoFileName: koffi.array("uint8", 255), }); let lib = null; let running = false; -// 解码 GBK 字符串 -function decodeGBK(buffer) { - // 找到第一个 null 字节 (0x00) 的位置 +// 解码字符串 (尝试 UCS-2/UTF-16LE) +function decodeString(buffer) { + // 这里的 buffer 是 uint8 数组,先转为 Buffer + const buf = Buffer.from(buffer); + + // 很多读卡器 DLL 返回的是 UCS-2 (UTF-16LE) + // 也有可能是 GBK。我们可以通过检查字节特征来判断,或者优先尝试 UCS-2 + // UCS-2 的特征是每两个字节一个字符,对于 ASCII 字符,高字节通常是 0x00 + + // 尝试作为 UTF-16LE 解码 + // 找到双 null 结尾 (0x00 0x00) let nullIndex = -1; - for (let i = 0; i < buffer.length; i++) { - if (buffer[i] === 0) { + for (let i = 0; i < buf.length - 1; i += 2) { + if (buf[i] === 0 && buf[i + 1] === 0) { nullIndex = i; break; } } - // 如果找到了 null,截取前面的部分;否则使用整个 buffer - const validBuffer = nullIndex !== -1 ? buffer.slice(0, nullIndex) : buffer; - return iconv.decode(validBuffer, "gbk").trim(); + const validBuf16 = nullIndex !== -1 ? buf.slice(0, nullIndex) : buf; + const str16 = iconv.decode(validBuf16, "utf16le").trim(); + + // 如果解码出来的字符串看起来是乱码(包含很多 )或者为空但 buffer 不为空,可能需要尝试 GBK + // 但通常 Syn_IDCardRead.dll 返回的是 UCS-2 + // 让我们先打印一下原始 hex 以便调试 + // parentPort.postMessage({ type: 'log', payload: `Hex: ${buf.slice(0, 10).toString('hex')}` }); + + return str16; } // 加载 DLL @@ -188,16 +202,16 @@ async function startListen() { if (ret === 0 && data) { const payload = { - name: decodeGBK(Buffer.from(data.Name)), - sex: decodeGBK(Buffer.from(data.Sex)), - nation: decodeGBK(Buffer.from(data.Nation)), - born: decodeGBK(Buffer.from(data.Born)), - address: decodeGBK(Buffer.from(data.Address)), - id_card_no: decodeGBK(Buffer.from(data.IDCardNo)), - grant_dept: decodeGBK(Buffer.from(data.GrantDept)), - life_begin: decodeGBK(Buffer.from(data.UserLifeBegin)), - life_end: decodeGBK(Buffer.from(data.UserLifeEnd)), - photo_path: decodeGBK(Buffer.from(data.PhotoFileName)), + name: decodeString(data.Name), + sex: decodeString(data.Sex), + nation: decodeString(data.Nation), + born: decodeString(data.Born), + address: decodeString(data.Address), + id_card_no: decodeString(data.IDCardNo), + grant_dept: decodeString(data.GrantDept), + life_begin: decodeString(data.UserLifeBegin), + life_end: decodeString(data.UserLifeEnd), + photo_path: decodeString(data.PhotoFileName), }; parentPort.postMessage({