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

Delphi解码QR码Base64字符串遇Unicode编码映射错误求助

Delphi Base64解码混合数据时的编码错误解决方法

错误原因分析

你遇到的No mapping for the Unicode character exists in the target multi-byte code page错误,本质是解码后的字节数组并非纯UTF-8文本,而是包含二进制结构的混合数据(比如数值、日期的二进制编码、自定义格式标识等)。直接用TEncoding.UTF8.GetString转换时,非法的UTF-8字节序列会触发编码映射失败。

正确的处理步骤

1. 先确保Base64解码到字节数组(这一步不会报错)

首先成功将Base64字符串解码为原始字节流,这是后续解析的基础:

var
  QRstr: string;
  DecodedBytes: TBytes;
begin
  QRstr := 'AT9NVU5JUiBBQkRVTExBSCBBTE1VTklGIEZBQ1RPUlkgRk9SIFBMQVNUSUMgUElQRVMgJiBGSVRUSU5HUyBDTy4CDzMwMDUyODA3OTYwMDAwMwMTMjAyNC0xMC0xM1QwNDo0MDoyMwQINDM5NTIuNDEFBzU3MzIuOTIGLFdPMkt1TE9CS2tkMkdRSnU1ZTA3Zzd3RU5vVXFoVy92UFZVTzA5UkdWTzQ9B2BNRVFDSUVPYm95MjRmNExMYzRFeDlEdkpqbUxnYU5BWS9Ybmo2UGhlUWNxYVYwbUxBaUJjVDZlZ2VpKzBXMFhNbVc1bW9FOWh5QUFwdjJCRUtXS2t6dWJ5UENKSGdnPT0IWDBWMBAGByqGSM49AgEGBSuBBAAKA0IABKjKpalSynCgT1a7cnHqONrPEWyCpcqx2PLnhzmXsH1CtjSbfljxm5adWyeZ2ekTcynTBhMXAkmW85x+SGllB5w=';
  try
    DecodedBytes := TNetEncoding.Base64.DecodeStringToBytes(QRstr);
    ShowMessageFmt('Base64解码成功,原始字节数:%d', [Length(DecodedBytes)]);
  except
    on E: Exception do
      ShowMessage('Base64解码失败:' + E.Message);
  end;
end;

2. 根据数据格式解析混合字节

由于数据包含文本、日期、数值等混合类型,必须依据该QR码的格式规范(比如字段偏移、长度、类型定义)来逐个解析字节。以下是通用示例(需根据实际格式调整):

var
  QRstr: string;
  DecodedBytes: TBytes;
  Stream: TMemoryStream;
  Reader: TBinaryReader;
  TextLen: Byte;
  TextContent: string;
  DateValue: TDateTime;
  Num1, Num2: Double;
begin
  QRstr := 'AT9NVU5JUiBBQkRVTExBSCBBTE1VTklGIEZBQ1RPUlkgRk9SIFBMQVNUSUMgUElQRVMgJiBGSVRUSU5HUyBDTy4CDzMwMDUyODA3OTYwMDAwMwMTMjAyNC0xMC0xM1QwNDo0MDoyMwQINDM5NTIuNDEFBzU3MzIuOTIGLFdPMkt1TE9CS2tkMkdRSnU1ZTA3Zzd3RU5vVXFoVy92UFZVTzA5UkdWTzQ9B2BNRVFDSUVPYm95MjRmNExMYzRFeDlEdkpqbUxnYU5BWS9Ybmo2UGhlUWNxYVYwbUxBaUJjVDZlZ2VpKzBXMFhNbVc1bW9FOWh5QUFwdjJCRUtXS2t6dWJ5UENKSGdnPT0IWDBWMBAGByqGSM49AgEGBSuBBAAKA0IABKjKpalSynCgT1a7cnHqONrPEWyCpcqx2PLnhzmXsH1CtjSbfljxm5adWyeZ2ekTcynTBhMXAkmW85x+SGllB5w=';
  DecodedBytes := TNetEncoding.Base64.DecodeStringToBytes(QRstr);
  
  Stream := TMemoryStream.Create;
  Reader := TBinaryReader.Create(Stream);
  try
    Stream.WriteBuffer(DecodedBytes[0], Length(DecodedBytes));
    Stream.Position := 0;
    
    // 示例:读取文本字段(假设第一个字节是文本长度)
    TextLen := Reader.ReadByte;
    TextContent := TEncoding.UTF8.GetString(Reader.ReadBytes(TextLen));
    ShowMessage('文本内容:' + TextContent);
    
    // 示例:读取日期(假设为TDateTime二进制格式,占8字节)
    DateValue := Reader.ReadDouble;
    ShowMessage('日期:' + DateTimeToStr(DateValue));
    
    // 示例:读取数值字段
    Num1 := Reader.ReadDouble;
    Num2 := Reader.ReadDouble;
    ShowMessageFmt('数值1:%.2f,数值2:%.2f', [Num1, Num2]);
    
    // 剩余字节可根据格式规范继续解析
  finally
    Reader.Free;
    Stream.Free;
  end;
end;

关键注意事项

  • 必须获取该QR码数据的官方格式文档,明确每个字段的位置、数据类型、编码方式,否则无法准确解析混合数据。
  • 如果文本部分使用非UTF-8编码(如ASCII、GB2312),需替换对应的TEncoding类型(比如TEncoding.ASCII.GetString)。
  • 绝对不要直接将整个混合字节数组转换为UTF-8字符串,仅对明确为文本的字节片段进行编码转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 05:42:43