base64解码文件不等于原始未编码文件

Posted

技术标签:

【中文标题】base64解码文件不等于原始未编码文件【英文标题】:base64 decoded file is not equal to the original unencoded file 【发布时间】:2012-02-17 22:47:50 【问题描述】:

我有一个普通的 pdf 文件 A.pdf ,第三方将文件编码为 base64 并将其作为长字符串在网络服务中发送给我(我无法控制第三方)。

我的问题是,当我使用 java org.apache.commons.codec.binary.Base64 解码字符串并将输出正确输出到名为 B.pdf 的文件时 我希望 B.pdf 与 A.pdf 相同,但 B.pdf 与 A.pdf 有点不同。因此,Acrobat 无法将 B.pdf 识别为有效的 pdf。

base64 有不同类型的编码\字符集机制吗?我可以检测我收到的字符串是如何编码的,以便 B.pdf=A.pdf 吗?

编辑-这是我要解码的文件,解码后应该以pdf格式打开

my encoded file


这是在记事本++中打开的文件的标题

**A.pdf**
        %PDF-1.4
        %±²³´
        %Created by Wnv/EP PDF Tools v6.1
        1 0 obj
        <<
        /PageMode /UseNone
        /ViewerPreferences 2 0 R
        /Type /Catalog

  **B.pdf**
        %PDF-1.4
        %±²³´
        %Created by Wnv/EP PDF Tools v6.1
        1 0! bj
        <<
        /PageMode /UseNone
        /ViewerPreferences 2 0 R
        /]
        pe /Catalog

这就是我解码字符串的方式

private static void decodeStringToFile(String encodedInputStr,
            String outputFileName) throws IOException 
        BufferedReader in = null;
        BufferedOutputStream out = null;
        try 
            in = new BufferedReader(new StringReader(encodedInputStr));
        out = new BufferedOutputStream(new FileOutputStream(outputFileName));
            decodeStream(in, out);
            out.flush();
         finally 
            if (in != null)
                in.close();
            if (out != null)
                out.close();
        
    

    private static void decodeStream(BufferedReader in, OutputStream out)
            throws IOException 
        while (true) 
            String s = in.readLine();
            if (s == null)
                break;
            //System.out.println(s);
            byte[] buf = Base64.decodeBase64(s);
            out.write(buf);
        

    

【问题讨论】:

我过去在使用Strings 时也看到过类似的结果。您可以尝试使用原始的 byte[]s 来代替,看看它是否有所作为。 您还需要显示执行 base64 编码的代码块。 我只从第三方获取字符串。我应该使用 String.getBytes(charset) 将字符串转换为字节吗?我怎么知道要使用什么字符集? 我没有编码代码,正如我所说,它来自第三方,我无法使用()它甚至在 java 中也没有。 【参考方案1】:

    您正在通过逐行工作来破坏解码。 Base64 解码器只是忽略空格,这意味着原始内容中的一个字节很可能被分成两个 Base64 文本行。您应该将所有行连接在一起并一次解码文件。

    Base64 类方法提供内容时,首选使用byte[] 而不是StringString 暗示字符集编码,可能不是你想要的。

【讨论】:

将所有行连接到一个字符串不起作用,使用 String.getBytes() 也不起作用。实际上,这两种方法给出的结果比原始结果更差(b 与 a 非常不同) @dov.amir:也许您应该发布一个服务器发送的 Base64 数据样本,以便我们了解发生了什么。无论如何,在一般情况下,逐行解码 Base64 内容仍然中断,除非这些行被拆分为 4 个字符的倍数。 @dov.amir: 1. 换行肯定有问题,因为每行正好有 74 个 base64 字符。这可能是您在 PDF 标题中看到的损坏的原因。 2. 你确定base64流吗?您上传的文件正好包含 118,602 个字符,而不是应有的 4 的倍数。如果您的链接确实应该包含整个文件,那么问题似乎出在 Base64 解码之前的某个地方。源 PDF 文件的大小是多少? 解决了!在我设法让第 3 方将文本编码为长度为 72 的行而不是长度为 74 的行之后,我的解码工作。 @dov.amir:这将使行长度成为 4 的倍数,这将解决您代码中的问题。不过,IMO 最好修复您自己的代码:Be liberal in what you accept, and conservative in what you send. 毕竟,对于 Base64 编码器来说,74 是相当典型的行长......

以上是关于base64解码文件不等于原始未编码文件的主要内容,如果未能解决你的问题,请参考以下文章

尝试在已用 Java 编码的 JS 中解码 Base64 时出现“要解码的字符串未正确编码”错误

Base64 编码的字符串到文件(Ruby on Rails) - 未定义的方法“解包”错误

Base64编码

java对文件的二进制流base64编码解码

在python中将base64编码的图像解码为原始图像

LoadRunner中Base64编码解码