解码 Java 中的 Base64 字符串
Decoding Base64 String in Java
我正在使用 Java 并且我有一个 Base64 编码的字符串,我希望对其进行解码,然后进行一些操作来进行转换。
正确的解码值是在Java脚本中通过函数atob()
获得的,但是在java中,使用Base64.decodeBase64()
我无法获得相等的值。
示例:
对于:
String str = "AAAAAAAAAAAAAAAAAAAAAMaR+ySCU0Yzq+AV9pNCCOI="
使用 Java脚本 atob(str)
我得到 ->
"Æ‘û$‚SF3«àö“Bâ"
使用 Java new String(Base64.decodeBase64(str))
我得到 ->
"Æ?û$?SF3«à§ö?â"
我可以解决此问题的另一种方法是 运行 Java 使用 Nashorn 引擎在 Java 中编写脚本,但我在 "$"
附近遇到错误符号。
当前代码:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
String script2 = "function decoMemo(memoStr){ print(atob(memoStr).split('')" +
".map((aChar) => `0${aChar.charCodeAt(0).toString(16)}`" +
".slice(-2)).join('').toUpperCase());}";
try {
engine.eval(script2);
Invocable inv = (Invocable) engine;
String returnValue = (String)inv.invokeFunction("decoMemo", memoTest );
System.out.print("\n result: " + returnValue);
} catch (ScriptException | NoSuchMethodException e1) {
e1.printStackTrace();
如有任何帮助,我们将不胜感激。我找了很多地方都找不到正确答案。
byte[] data = Base64.getDecoder().decode(str);
btoa
已损坏,不应使用。
问题是,字节不是字符。 Base64 编码只做一件事。它将 bytes 转换为几乎可以在任何 text-based 传输机制中存活的字符流。而 Base64 解码则相反,它将这些字符转换为 bytes.
令人困惑的是,您正在打印这些字节,就好像它们是字符一样。他们不是。
你最终得到完全相同的字节,但是 javascript 和 java 不同意你应该如何把它变成一个 ersatz 字符串,因为你试图将它打印到一个控制台。这是一个错误——字节不是字符。因此,正在使用某种字符集编码,而您不需要任何这些,因为这些字符显然不打算像那样打印。
Java 脚本排序 half-equates 字符和字节,并会自由地将一个转换为另一个,选择一些随机编码。钱币。 Java脚本在这方面很糟糕,它就是这样。 MDN docs on btoa
解释了为什么你不应该使用它。您 运行 遇到了 那个 问题。
不完全确定您如何在 java脚本中修复它 - 但也许您不需要它。 Java 对字节的解码非常好,javascript 也是如此,但是 javascript 然后将这些字节转换为一些愚蠢的字符,这就是问题所在。
你所拥有的根本不是文本字符串。赠品是开头的 AA。那些映射到许多零字节。这不会转换为任何标准字符集中有意义的文本。
所以你所拥有的很可能是二进制数据。将其转换为字符串不会为您提供有意义的文本。
现在解释一下您在 Java 和 Java 脚本之间看到的区别。在我看来,Java 和 Javascript 都在“尽最大努力”尝试转换二进制数据,就好像它是在 ISO-8859-1(又名 ISO LATIN-1)中编码的一样.
问题是一些字节代码映射到未分配的代码。
- 在 Java 的情况下,那些未分配的代码被映射到
?
,无论是在创建字符串时还是在输出时。
- 在 Java脚本情况下,未分配的代码未包含在字符串中,或者当您尝试显示它们时它们被删除了。
作为记录,这就是我上面的在线 base64 解码器的方式:
����������������Æû$SF3«àöBâ
未分配的代码是0x91 0x82和0x93。 0x15 和 0x0B 是 non-printing 控制代码。
但最重要的是,您不应在 Java 或 Java 脚本中将此数据转换为字符串。它应该被视为二进制;即字节值数组。
我正在使用 Java 并且我有一个 Base64 编码的字符串,我希望对其进行解码,然后进行一些操作来进行转换。
正确的解码值是在Java脚本中通过函数atob()
获得的,但是在java中,使用Base64.decodeBase64()
我无法获得相等的值。
示例:
对于:
String str = "AAAAAAAAAAAAAAAAAAAAAMaR+ySCU0Yzq+AV9pNCCOI="
使用 Java脚本 atob(str)
我得到 ->
"Æ‘û$‚SF3«àö“Bâ"
使用 Java new String(Base64.decodeBase64(str))
我得到 ->
"Æ?û$?SF3«à§ö?â"
我可以解决此问题的另一种方法是 运行 Java 使用 Nashorn 引擎在 Java 中编写脚本,但我在 "$"
附近遇到错误符号。
当前代码:
ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
String script2 = "function decoMemo(memoStr){ print(atob(memoStr).split('')" +
".map((aChar) => `0${aChar.charCodeAt(0).toString(16)}`" +
".slice(-2)).join('').toUpperCase());}";
try {
engine.eval(script2);
Invocable inv = (Invocable) engine;
String returnValue = (String)inv.invokeFunction("decoMemo", memoTest );
System.out.print("\n result: " + returnValue);
} catch (ScriptException | NoSuchMethodException e1) {
e1.printStackTrace();
如有任何帮助,我们将不胜感激。我找了很多地方都找不到正确答案。
byte[] data = Base64.getDecoder().decode(str);
btoa
已损坏,不应使用。
问题是,字节不是字符。 Base64 编码只做一件事。它将 bytes 转换为几乎可以在任何 text-based 传输机制中存活的字符流。而 Base64 解码则相反,它将这些字符转换为 bytes.
令人困惑的是,您正在打印这些字节,就好像它们是字符一样。他们不是。
你最终得到完全相同的字节,但是 javascript 和 java 不同意你应该如何把它变成一个 ersatz 字符串,因为你试图将它打印到一个控制台。这是一个错误——字节不是字符。因此,正在使用某种字符集编码,而您不需要任何这些,因为这些字符显然不打算像那样打印。
Java 脚本排序 half-equates 字符和字节,并会自由地将一个转换为另一个,选择一些随机编码。钱币。 Java脚本在这方面很糟糕,它就是这样。 MDN docs on btoa
解释了为什么你不应该使用它。您 运行 遇到了 那个 问题。
不完全确定您如何在 java脚本中修复它 - 但也许您不需要它。 Java 对字节的解码非常好,javascript 也是如此,但是 javascript 然后将这些字节转换为一些愚蠢的字符,这就是问题所在。
你所拥有的根本不是文本字符串。赠品是开头的 AA。那些映射到许多零字节。这不会转换为任何标准字符集中有意义的文本。
所以你所拥有的很可能是二进制数据。将其转换为字符串不会为您提供有意义的文本。
现在解释一下您在 Java 和 Java 脚本之间看到的区别。在我看来,Java 和 Javascript 都在“尽最大努力”尝试转换二进制数据,就好像它是在 ISO-8859-1(又名 ISO LATIN-1)中编码的一样.
问题是一些字节代码映射到未分配的代码。
- 在 Java 的情况下,那些未分配的代码被映射到
?
,无论是在创建字符串时还是在输出时。 - 在 Java脚本情况下,未分配的代码未包含在字符串中,或者当您尝试显示它们时它们被删除了。
作为记录,这就是我上面的在线 base64 解码器的方式:
����������������Æû$SF3«àöBâ
未分配的代码是0x91 0x82和0x93。 0x15 和 0x0B 是 non-printing 控制代码。
但最重要的是,您不应在 Java 或 Java 脚本中将此数据转换为字符串。它应该被视为二进制;即字节值数组。