如何在有符号字节的C#中编码/解码来自Java的有符号字节的Base64字符串?

xxslljrj  于 2023-03-06  发布在  Java
关注(0)|答案(2)|浏览(204)

Java中长度为8且值为Byte.MIN_VALUE的字节数组:

byte[] bytes = new byte[8];
Arrays.fill(bytes, Byte.MIN_VALUE);
// [-127, -127, -127, -127, -127, -127, -127, -127]
string base64string = Base64.getEncoder().encodeToString(bytes);

当我把这个字节数组编码成Base64时,结果是:gICAgICAgIA=
但是,当C#解码此数组时,结果为[128, 128, 128, 128, 128, 128, 128, 128],因为C#的字节是无符号的。预期结果应为[0, 0, 0, 0, 0, 0, 0, 0]
C#的字节数组byte.MinValue生成Base64字符串AAAAAAAAAAA=,Java将此Base64字符串解码为[0, 0, 0, 0, 0, 0, 0, 0],而不是预期的结果[-127, -127, -127, -127, -127, -127, -127, -127]
C#中的解码使用Convert.ToBase64String(bytes)完成。
有没有办法把Java的字节转换成无符号字节,然后用Base64编码,这样C#就可以正确地解码它们?或者C#有没有办法把Java的无符号字节的Base64编码字节数组转换成有符号字节的Base64编码字节数组?
我还应该提到,我还希望能够将C#的字节数组编码为Base64,以便在Java中正确读取。

iibxawm4

iibxawm41#

编码字符串“gICAgICAgIA=”代表二进制“10000000 1000000 1000000 10000000 10000000 10000000 10000000 10000000”。https://cryptii.com/pipes/base64-to-binary
二进制10000000 = -128(对于有符号字节)和10000000 = 128(对于无符号字节)。在.NET中,Byte是无符号字节,SByte是有符号字节的类型。范围与Java相同。
使用sbyte[]代替byte[]。Byte是范围为0到255的8位无符号整数,而sbyte是范围为-128到127的8位有符号整数。

using System;
                    
public class Program
{
    public static void Main()
    {
        var x = Convert.FromBase64String("gICAgICAgIA=");
        // Print as Signed Bytes
        foreach(var sb in x)
        {
            Console.Write($"{(SByte)sb} ");
        }
        Console.WriteLine();
        // Print as Unsigned Bytes
        foreach(var b in x)
        {
            Console.Write($"{b} ");
        }
    }
}

其输出为

-128 -128 -128 -128 -128 -128 -128 -128 
128 128 128 128 128 128 128 128
dtcbnfnu

dtcbnfnu2#

结果是一致的:

Java: Byte.MIN_VALUE = -128, binary representation: '10000000' 
C#:   byte.MinValue  = 0   , binary representation: '00000000'

你不能期望相同的基64字符串。在某些地方,你缺少你正在使用的两种不同类型之间的转换。

相关问题