jjzjj

Java 和 .NET : Base64 conversion confusion

coder 2024-03-28 原文

我在将文本转换为 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);

我的 .NET 代码是:

Dim c As String = Chr(65)
Dim result as String = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(c))

它们都返回相同的结果:“QQ==”。这可以。但是当我尝试转换一个特殊字符时,例如字符代码 153。然后它返回不同的结果。

char a = 153;
String c = String.valueOf(a);               
byte bt[] = c.getBytes();               
String result = Base64.encodeToString(bt, Base64.DEFAULT);

返回“wpk=”

和我相同的 .NET 代码:

Dim c As String = Chr(153) 
Dim result as String = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(c))

返回“4oSi”

这太奇怪了。这里有什么问题。我在两个平台上都使用 native Base64 库。我的代码有问题吗?

最佳答案

由于您正在编码的数据是加密数据 - 任何字节可以从 0 到 255 的随机数据,并且在其加密状态下,没有字符或文本含义,您需要将此信息视为 - 让我们称之为- 真正的二进制数据。 Java 和 .NET 都通过各自的字节数组原语完全支持真正的二进制数据。

如您所知,base64 编码是将真正的二进制数据(范围为 0 到 255)转换为稍大的二进制数据数组(其中每个字节保证具有与 ASCII 可打印字符相同的值)的过程介于 32 和 126 之间)。我们称此为编码二进制。然后可以将编码的二进制安全地转换为文本,因为几乎每个已知字符集都同意可打印的 ASCII 字符集(32 到 126)。

所以 Java 和 VB.NET 片段的主要问题是您试图使用文本原语——Java 中的 char 和 String; VB.NET 中的字符串,用于存储真正的二进制 数据。一旦你这样做就太晚了。没有办法将它可靠地转换回字节数组,因为文本基元的设计根本不是为了安全地存储和检索二进制数据。有关为什么会这样的更多信息,请阅读 The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)

幸运的是,修复很简单。对于 Java,不要使用 char 和 String 来存储二进制数据。将数据直接放入字节数组。尝试以下操作:

  byte [] bt = new byte[1];
  bt[0] = (byte) 153;
  String result = Base64.encodeToString(bt, Base64.DEFAULT);

我得到 mQ==

修复在 VB.NET 中在概念上是相同的。不要使用字符串。使用字节数组。

    Dim bytes() As Byte = New Byte() {153}
    Dim result As String = Convert.ToBase64String(bytes)

同样 - 答案是 mQ==

最后,经过编码,使用Strings就完全没问题了。您的字符位于 ASCII 子集中,字符串和字节数组之间的任何转换都不会破坏数据,因为所有字符集都同意 ASCII 子集。

请记住,您将遇到相同的问题,但顺序相反 - 解码。您将解码为字节数组,此时您将返回到 true binary。从这一点开始,数据绝不能存储为字符串 - 直到你完成它 - 例如。将其解密回原始明文。

希望这对您有所帮助。

关于Java 和 .NET : Base64 conversion confusion,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13017703/

有关Java 和 .NET : Base64 conversion confusion的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  3. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  4. ruby - 如何模拟 Net::HTTP::Post? - 2

    是的,我知道最好使用webmock,但我想知道如何在RSpec中模拟此方法:defmethod_to_testurl=URI.parseurireq=Net::HTTP::Post.newurl.pathres=Net::HTTP.start(url.host,url.port)do|http|http.requestreq,foo:1endresend这是RSpec:let(:uri){'http://example.com'}specify'HTTPcall'dohttp=mock:httpNet::HTTP.stub!(:start).and_yieldhttphttp.shou

  5. java - 等价于 Java 中的 Ruby Hash - 2

    我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/

  6. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  7. java - 从 JRuby 调用 Java 类的问题 - 2

    我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www

  8. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  9. java - 我的模型类或其他类中应该有逻辑吗 - 2

    我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我

  10. java - 什么相当于 ruby​​ 的 rack 或 python 的 Java wsgi? - 2

    什么是ruby​​的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht

随机推荐