我在将文本转换为Java(Android)和.NET(Visual Basic)中的Base64字符串时遇到问题.简单(可读)形式的ASCII字符转换得很好.但是当谈到特殊字符(代码大于128的字符)时,它们会给我带来麻烦.
例如,我尝试转换ASCII值为65(字符"A")的字符代码.
我的Java代码是:
char a = 65;
String c = String.valueOf(a);
byte bt[] = c.getBytes();
String result = Base64.encodeToString(bt, Base64.DEFAULT);
Run Code Online (Sandbox Code Playgroud)
我的.NET代码是:
Dim c As String = Chr(65)
Dim result as String = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(c))
Run Code Online (Sandbox Code Playgroud)
这两个都返回相同的结果:"QQ ==".这可以.但是当我尝试转换特殊字符时,例如字符代码153.然后它返回不同的结果.
char a = 153;
String c = String.valueOf(a);
byte bt[] = c.getBytes();
String result = Base64.encodeToString(bt, Base64.DEFAULT);
Run Code Online (Sandbox Code Playgroud)
这返回"wpk ="
和我相同的.NET代码:
Dim c As String = Chr(153)
Dim result as String = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(c))
Run Code Online (Sandbox Code Playgroud)
返回"4oSi"
这太奇怪了.这里有什么不对.我在两个平台上都使用本机Base64库.我的代码有问题吗?
Gui*_*one 10
由于您编码的数据是加密数据 - 随机数据,其中任何字节可以是0到255,并且在加密状态下,没有字符或文本含义,您需要将此信息视为-lets调用它 - true binary数据.Java和.NET都通过各自的字节数组原语完全支持真正的二进制数据.
如您所知,base64编码是将真正的二进制数据(范围为0到255)转换为稍大的二进制数据数组的过程(其中每个字节保证与32位之间的ASCII可打印字符具有相同的值.和126).我们称之为encoded binary.然后encoded binary可以安全地转换为文本,因为几乎每个已知的字符集都与可打印的ASCII字符集(32到126)一致.
所以Java和VB.NET片段的主要问题是你试图在Java中使用文本原语 - char和String; VB.NET中用于存储true binary数据的字符串.一旦你这样做,为时已晚.没有办法可靠地将其转换回字节数组,因为文本原语并不是为了安全地存储和检索二进制数据而设计的.有关为什么会出现这种情况的更多信息,请阅读绝对最低限度的软件开发人员,绝对必须知道Unicode和字符集(没有任何借口!)
幸运的是,修复很简单.对于Java,不要使用char和String来存储二进制数据.将数据直接放入字节数组中.请尝试以下方法:
byte [] bt = new byte[1];
bt[0] = (byte) 153;
String result = Base64.encodeToString(bt, Base64.DEFAULT);
Run Code Online (Sandbox Code Playgroud)
我得到mQ ==
在VB.NET中,修复在概念上是相同的.不要使用String.使用字节数组.
Dim bytes() As Byte = New Byte() {153}
Dim result As String = Convert.ToBase64String(bytes)
Run Code Online (Sandbox Code Playgroud)
再次 - 答案是mQ ==
最后,在编码之后,使用字符串完全没问题.您的字符在ASCII子集中,字符串和字节数组之间的任何转换都不会损坏数据,因为所有字符集都与ASCII子集一致.
请记住,您将以相反的顺序出现相同的问题 - 解码.您将解码为一个字节数组,此时您将返回true binary.从这一点开始,数据绝不能存储为字符串 - 直到你完成它 - ex.将其解密回原始明文.
希望这可以帮助.