You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript中Unhexlify转换字节失效导致文件损坏问题求助

问题描述

需要从Python向JavaScript传输Excel文件,受约束必须转为字符串传输。Python端读取Excel文件字节并转为十六进制字符串的代码如下:

with open(EXCEL_TEMPLATE_OUTPUTS, "rb") as f:
    encrypted_bytes = f.read()

return encrypted_bytes.hex()

在JavaScript端将十六进制字符串转回字节数组以创建Blob时,使用的函数存在问题:

var unhexlify = function(str) {
var bytes = [];
for (var i=0, l=str.length; i<l; i+=2) {
  bytes.push(String.fromCharCode(parseInt(str.substr(i, 2), 16)));
}
return bytes;
}

该函数多数情况正常,但部分字节转换错误,例如十六进制值"c8"被转换为字符"È"而非原始字节"\xc8",导致重建的文件损坏。

示例验证:

  • JavaScript代码:
console.log(String.fromCharCode(parseInt("c8", 16)));

输出为"È"而非"\xc8";

  • Python代码:
from binascii import hexlify, unhexlify
unhexlify("c8")
# b'\xc8'
bytes.fromhex('c8')
# b'\xc8'
解决方法

问题出在String.fromCharCode的使用上:它会将字节值当作Unicode字符编码来转换,而我们需要的是原始的二进制字节数据。正确的做法是直接使用Uint8Array来存储每个字节的数值,避免字符编码转换带来的失真。

修改后的JavaScript函数:

function hexToBytes(str) {
  const bytes = new Uint8Array(str.length / 2);
  for (let i = 0; i < str.length; i += 2) {
    bytes[i / 2] = parseInt(str.substr(i, 2), 16);
  }
  return bytes;
}

使用这个函数还原字节后,就可以直接用来创建Blob并生成文件:

const hexStr = "你的十六进制字符串";
const byteArray = hexToBytes(hexStr);
const blob = new Blob([byteArray], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
// 后续可通过URL.createObjectURL(blob)下载文件
原理说明
  • Uint8Array是JavaScript的类型化数组,专门用于存储8位无符号整数(0-255),正好对应二进制文件的每个字节值,不会进行任何字符编码转换,能精准还原原始字节。
  • 原函数用String.fromCharCode会把字节值映射到Unicode字符集中的对应字符,对于大于127的字节值(如0xc8=200),会被当作Latin-1或UTF-16编码的字符,导致原始字节值丢失,最终文件损坏。

内容的提问来源于stack exchange,提问作者Avatar36

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 00:52:42