Java和C之间的Base64和二进制流#
我觉得答案很明显,但假设我有以下C# Java中的以下内容(好的,是Scala,但使用Java库): 我得到了完全不同的64进制字符串。他们在这里有什么不同?我需要Java输出与.NET输出匹配。我假设这是某种字节排序问题,但我没有运气使用Java和C之间的Base64和二进制流#,java,c#,scala,base64,Java,C#,Scala,Base64,我觉得答案很明显,但假设我有以下C# Java中的以下内容(好的,是Scala,但使用Java库): 我得到了完全不同的64进制字符串。他们在这里有什么不同?我需要Java输出与.NET输出匹配。我假设这是某种字节排序问题,但我没有运气使用ByteBuffer来纠正这个问题 爪哇: PczMzT3MzM0/GaAACZMZMQAAAAD3MZM0/GaAAQAAABRN8XZAAAAAAAAAAAAAAAAAAAAAAAAAQ== C#(带有未知=符号,因为我们出于某种原因将其切掉): zczM
ByteBuffer
来纠正这个问题
爪哇:
PczMzT3MzM0/GaAACZMZMQAAAAD3MZM0/GaAAQAAABRN8XZAAAAAAAAAAAAAAAAAAAAAAAAAQ==
C#(带有未知=符号,因为我们出于某种原因将其切掉):
zczMPc3MzD0AAIA/ZCZMPQAAAAAAAAAM3MZD0AAIA/AFPFN1EBAAAAAAAAAAAAAAAAAA
我真的觉得好像是字节排序,这就是为什么我尝试在Java代码order方法中使用ByteBuffer
来更改排序,但没有成功
为了进一步澄清,Java代码在x86_64 CentOS Java 7上运行,.NET在x86_64 Windows Server 2008.NET 4上运行。这些值来自Protobuf对象,因此我认为它们应该是非常跨平台的。从数字上讲,无论我输入了什么,数据都是相同和一致的,至少当我至少写这三种数据类型时。唯一显著的区别是Java中缺少无符号类型,可能存在二进制表示的差异,这是我最初试图解决的问题,但我似乎无法解决
正如我所说。使用其他格式不是一个选项。我需要从java编写二进制数据,然后对base 64进行编码,以得到与.NET相同的结果。序列化选项不是选项。一定是这样。我需要一个资源,将有助于把这一切结合起来,无论这意味着字节数据的二进制操作与否。我需要对数据类型进行一些解释,因为我已经进行了大量搜索,但没有找到一个资源来解释如何做到这一点或真正的区别是什么,因此我可以实现我决定在这里提出的解决方案。不同的平台有不同的二进制表示。如果要匹配base64字符串,应该使用json或xml序列化。提供跨平台的Json或xml
编辑:别误会我:Base64是标准的编码算法。它为相同的数据提供相同的输出。我的意思是字节数组可能不同。不同的平台有不同的二进制表示。如果要匹配base64字符串,应该使用json或xml序列化。提供跨平台的Json或xml
编辑:别误会我:Base64是标准的编码算法。它为相同的数据提供相同的输出。我的意思是字节数组可能不同。如何实现跨平台二进制通信:
- 定义精确的字节格式
- 在每个平台上实现
- 整数类型的序列化可能因字节顺序/可能的替代表示(如.Net中的压缩int)而不同
- 布尔类型和枚举类型的大小可能不同
- 数组/字符串可以使用不同的类型来表示长度
- 填充可以由一些二进制表示添加
- 字符串可以是Utf8、Utf-16或任何其他指定/未指定的编码(带或不带尾随0)
- 定义精确的字节格式
- 在每个平台上实现
- 整数类型的序列化可能因字节顺序/可能的替代表示(如.Net中的压缩int)而不同
- 布尔类型和枚举类型的大小可能不同
- 数组/字符串可以使用不同的类型来表示长度
- 填充可以由一些二进制表示添加
- 字符串可以是Utf8、Utf-16或任何其他指定/未指定的编码(带或不带尾随0)
BinaryWriter
首先写入数据类型的低字节,而Java的DataOutputStream
首先写入高字节
此外,当您写入.NET无符号整数时,它会写入4个字节。但是当你写一个Java长的时,它会写8个字节。这就是另一个区别
但是,一旦你理解了它们之间的差异,将它们匹配起来其实并不难。这里有两个代码片段,一个在C#中,另一个在Java中,它们编码相同的信息并输出相同的Base64
-编码字符串。在我的例子中,我选择重写Java编写float
s和long
s的方式
.NET代码示例
static void Main(字符串[]args)
{
使用(MemoryStream ms=新MemoryStrea
using (MemoryStream ms = new MemoryStream())
{
using (BinaryWriter bw = new BinaryWriter(ms))
{
// Write some floats, bytes, and uints
// Convert.ToBase64String this stuff from ms.ToArray
}
}
val byteStream = new ByteArrayOutputStream()
val outStream = new DataOutputStream(byteStream)
// Write some floats, bytes, and longs where the uints were using
// writeFloat, writeByte, and writeLong. .NET has an overloaded
// function that takes whatever.
// Base64.getEncoder.encodeToString byteStream.toByteArray