Delphi11 FireMonkey下Base64解码报错:Unicode字符无多字节映射
解决Delphi 11中VCL/FMX跨环境Base64编解码的编码错误问题
错误原因
问题出在TNetEncoding.Base64对字符串的默认编解码逻辑上:当直接传入string类型参数时,它会依赖系统默认多字节编码将Unicode字符串转换为字节流。VCL环境下系统代码页可能兼容字符串中的所有字符,但FMX环境(尤其是跨平台或系统代码页不匹配场景)会遇到无法映射的Unicode字符,从而抛出No mapping for unicode character exists in target multi-byte code page错误。
解决方案
明确使用UTF-8编码处理字符串与字节流的转换,直接操作字节数组进行Base64编解码,彻底避免依赖系统默认编码的隐式转换。
修正后的代码
const salt : string = 'SECRET'; // 统一用string类型,避免UTF8String与string的隐式转换问题 procedure Tfmmain.Button1Click(Sender: TObject); var UTF8Bytes: TBytes; begin // 将拼接后的字符串转换为UTF-8字节数组 UTF8Bytes := TEncoding.UTF8.GetBytes(salt + Edit1.Text); // 对字节数组执行Base64编码,得到字符串结果 Edit2.Text := TNetEncoding.Base64.EncodeBytesToString(UTF8Bytes); end; procedure Tfmmain.Button2Click(Sender: TObject); var UTF8Bytes: TBytes; s : string; begin // 将Base64字符串解码为UTF-8字节数组 UTF8Bytes := TNetEncoding.Base64.DecodeStringToBytes(Edit2.Text); // 将UTF-8字节数组转换为Unicode字符串 s := TEncoding.UTF8.GetString(UTF8Bytes); // 移除salt内容 edit3.Text := StringReplace(s, salt, '', []); end;
关键说明
- 显式指定UTF-8编码:通过
TEncoding.UTF8.GetBytes和GetString强制使用UTF-8完成字符串与字节流的转换,保证VCL和FMX环境下的行为一致,同时支持所有Unicode字符。 - 直接操作字节数组:使用
EncodeBytesToString和DecodeStringToBytes方法绕开TNetEncoding.Base64对字符串的默认编码转换,从根源上消除编码不匹配的风险。 - 统一字符串类型:将
salt改为string类型,避免UTF8String与string拼接时的隐式编码转换,减少潜在问题。
内容的提问来源于stack exchange,提问作者Franz Andreani
相关产品推荐
相关产品推荐

