【问题标题】:Encoding a binary as BASE64 in Java and decoding it in node.js在 Java 中将二进制编码为 BASE64 并在 node.js 中解码
【发布时间】:2016-08-30 18:49:10
【问题描述】:

我有一个 Pentaho 进程,它是通过 java 对二进制 (pdf) 进行 base64 编码 - 使用以下命令:

步骤:在内存中加载文件内容 输出:pdf_content

然后

步骤:Javascript 输出:encString

var encString = new Packages.java.lang.String( Packages.org.apache.commons.codec.binary.Base64.encodeBase64( pdf_content.getBytes() ) );

然后

步骤:休息客户端(发布数据)

在 NodeJs 方面

const binary = new Buffer(base64Encoded, 'base64');

问题是节点端的二进制文件与源端的二进制文件不同(我可以访问并可以复制文件)。

我引入了一个中间步骤,在解码之前将 base64Encoded 字符串保存到磁盘,这进一步混淆了这个问题。然后我还打开了原始文件(来自 Pentaho 端)并使用

 Buffer(fs.readFileSync(originalPath)).toString('base64') 

并比较了每个的 base 64 编码版本。我希望确认算法是不同的(尽管不能保证)。文件本身的长度相同,并且开始和结束没有区别。散落在文件中的是一堆细微的差异。这里 1 个字节,那里 1 个字节。

其他位:Apache.Commons...Base64 使用“rfc 2045”Node Js 端的缓冲区使用“rfc 4648”(我可能误读了描述)。问题,

  1. 是否有已知的方式在 Java 编码和 Node Js 解码之间进行 base64 通信?
  2. 对于 Pentaho 中的 base64 编码还有其他建议吗?

【问题讨论】:

  • FWIW,RFC 4648 似乎是实际的 base64 编码,并提到满足 RFC 2045 的一些限制,因此乍一看它们似乎不兼容。
  • 是的,我也这么认为。我希望能够弄清楚如何在两者之间进行翻译,但这似乎不太可能。我似乎在节点端找不到兼容的实现......我认为我的 Java 实现仅限于预安装的 1.7

标签: javascript java node.js encoding pentaho


【解决方案1】:

这是您在 Java 端对其进行编码的方式:

在 Java 7 中使用 Google guava 的 com.google.common.io.BaseEncodingcom.google.common.io.Files

byte[] data = BaseEncoding.base64().encode(bytes).getBytes();
Files.write(data, new File(outputFile));

在 Java 8 中使用 java.util.Base64java.nio.file.Files/java.nio.file.Paths

byte[] data = Base64.getEncoder().encode(bytes);
Files.write(Paths.get(outputFile), data);

并在节点端解码(同步版):

var fs = require("fs");
var buf fs.readFileSync("fromJava.dat");
var res = new Buffer(buf.toString(), "base64").toString("utf-8");

下面是调用 node.js 进程并证明正确性的相应 Java 端测试(对于 Java8 原生 java.util.Base64 和 Guava 的 com.google.common.io.BaseEncoding):

@Test
public void testJ8() throws IOException {
  String input = "This is some UTF8 test data, which also includes some characters "
    + "outside the 0..255 range: ❊ ✓ ❦. Let's see how we get them to node and back";

  byte[] data = Base64.getEncoder().encode(input.getBytes());
  Files.write(Paths.get("fromJava.dat"), data);

  Process p = Runtime.getRuntime().exec(new String[]{"node",  "-e",
    "console.log(new Buffer(require('fs').readFileSync('fromJava.dat').toString(), 'base64').toString('utf-8'))"});
  assertEquals(input, new Scanner(p.getInputStream()).useDelimiter("\n").next());
}

试运行:

进程以退出代码 0 结束

@Test
public void testJ7() throws IOException {
  String input = "This is some UTF8 test data, which also includes some characters "
    + "outside the 0..255 range: ❊ ✓ ❦. Let's see how we get them to node and back";

  byte[] data = BaseEncoding.base64().encode(input.getBytes()).getBytes();
  Files.write(data, new File("fromJava.dat"));

  Process p = Runtime.getRuntime().exec(new String[]{"node",  "-e",
    "console.log(new Buffer(require('fs').readFileSync('fromJava.dat').toString(), 'base64').toString('utf-8'))"});
  assertEquals(input, new Scanner(p.getInputStream()).useDelimiter("\n").next());
}

试运行:

进程以退出代码 0 结束

在 OSX/unix 上使用 Java 8 执行的两个测试,但这里使用的 Guava 19 与 Java 7 完全兼容,如果 node 可执行文件在 Windows 的路径上,那么没有理由不在那里运行测试(前提是它还可以在 -e 参数之后评估脚本,不知道)。

【讨论】:

    猜你喜欢
    • 2011-08-13
    • 1970-01-01
    • 2012-09-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-02
    • 2014-11-06
    • 1970-01-01
    相关资源
    最近更新 更多