在Java中将二进制编码为BASE64并在node.js中对其进行解码

时间:2016-08-30 18:49:10

标签: javascript java node.js encoding pentaho

我有一个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 Side)并使用

对其进行编码
 Buffer(fs.readFileSync(originalPath)).toString('base64') 

并比较了每个的64位编码版本。我希望确认算法不同(虽然没有保证)。文件本身长度相同,开始和完成没有差异。分散在文件中的是一堆细微差别。 1字节,这里有1个字节。

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

  1. 是否有一种已知的方法在Java编码和Node Js解码之间传递base64?
  2. Pentaho还有其他关于base64编码的建议吗?

1 个答案:

答案 0 :(得分:0)

以下是在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");

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

@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参数之后评估一个脚本,不知道)。