C#与Java的Base64编码结果差异,源自JSON序列化时斜杠转义规则不同:Java默认转义斜杠,C#默认不转义。统一序列化规则,例如C#使用Newtonsoft.Json或配置System.Text.Json转义斜杠,即可使Base64结果一致。因为Base64编码中可能包含正斜杠字符,而Java会将其转义,导致差异,统一后即可解决。此方法可有效解决跨
C# 与 Ja va 的 Base64 编码结果不同,并非编码逻辑本身出了问题,而是 JSON 序列化时的行为差异在“捣鬼”。简单来说,Ja va 的 JSONObject.toString() 默认会对 URL 中的斜杠 / 进行转义,生成 \/;而 .NET 的 System.Text.Json.JsonSerializer 则默认不转义斜杠。这可不仅仅是写法不同,它直接导致原始字节数组不一样,Base64 结果自然也就大相径庭。
那么,怎样才能让 C# 和 Ja va 生成一模一样的 Base64 字符串呢?关键在于,让两者序列化出完全相同的 JSON 字符串——从引号、空格到斜杠转义,每一个字符都要对得上。
问题出在哪儿?其实就两点:
长期稳定更新的攒劲资源: >>>点此立即查看<<<
https:\/\/test.com\/...。https://test.com/...。关键在于,这两种写法虽然解码后语义完全等价,但在字节层面是不同的。比如,\/ 是两个字节(反斜杠和斜杠),而 / 只是一个字节。因此,Base64 编码的结果必然无法统一。
既然知道了原因,解决方案就明朗了。我们需要让 C# 的序列化行为与 Ja va 保持一致,也就是强制对斜杠进行转义。
不过要留意的是,System.Text.Json 在默认情况下,并没有提供直接开关来“仅针对斜杠进行转义”。因此,最直接、最稳妥的方式是换用兼容性更强的 Newtonsoft.Json(也就是 Json.NET)。当然,如果你必须使用 System.Text.Json,也有办法,只是需要额外配置。
这个方案最为简单直接,因为 Newtonsoft.Json 默认就对斜杠进行转义,和 Ja va 的 org.json 库行为一致。
// 安装包:Install-Package Newtonsoft.Json using Newtonsoft.Json; var claimSets = new Dictionary{ { "partnerUrl", "https://test.com/testapply/abc/signup" } }; // Newtonsoft 默认对 '/' 转义(与 org.json 行为一致) string claimSetsJson = JsonConvert.SerializeObject(claimSets); byte[] bytes = Encoding.UTF8.GetBytes(claimSetsJson); string base64 = Convert.ToBase64String(bytes); // 输出:eyJwYXJ0bmVyVXJsIjoiaHR0cHM6XC9cL3Rlc3QuY29tXC90ZXN0YXBwbHlcL2FiY1wvc2lnbnVwIn0= Console.WriteLine(base64);
如果你希望继续使用 System.Text.Json,从 .NET 6 开始,可以通过自定义 Ja vaScriptEncoder 来实现。核心思路是,创建一个编码器,把斜杠 / 加入到“需要额外转义的字符”列表中。
using System.Text.Encodings.Web;
using System.Text.Json;
var encoder = Ja vaScriptEncoder.Create(
UnicodeRanges.All, // 包含所有范围
'/'); // 显式添加 '/' 到需转义字符列表
var options = new JsonSerializerOptions
{
Encoder = encoder,
WriteIndented = false
};
string claimSetsJson = JsonSerializer.Serialize(claimSets, options);
byte[] bytes = Encoding.UTF8.GetBytes(claimSetsJson);
string base64 = Convert.ToBase64String(bytes);
注意:
Ja vaScriptEncoder.Create(...)的第二个参数是“额外需转义的字符”,把'/'传进去即可生效。
将 Ja va 输出的 Base64 字符串(例如 eyJwYXJ0bmVyVXJsIjoiaHR0cHM6XC9cL3Rlc3QuY29tXC90ZXN0YXBwbHlcL2FiY1wvc2lnbnVwIn0=)与 C# 任意一个方案输出的结果进行对比,你会发现它们完全一致。
统一序列化输出,才能保证 Base64 的确定性与互操作性。这不仅是技术细节,更是跨语言协作的工程实践。
侠游戏发布此文仅为了传递信息,不代表侠游戏网站认同其观点或证实其描述