解码来自xml文档的base64编码数据

Kje*_*sen 5 c# xml base64 decode

我收到一些带有嵌入式base64编码图像的xml文件,我需要将其解码并保存为文件.

可以在下面下载此类文件的未修改(除了压缩)示例:

20091123-125320.zip(60KB)

但是,我收到诸如"Base-64 char数组的长度无效"和"Base-64字符串中的无效字符"之类的错误.我在代码中标记了我在代码中得到错误的行.

文件可能如下所示:

<?xml version="1.0" encoding="windows-1252"?>
<mediafiles>
    <media media-type="image">
      <media-reference mime-type="image/jpeg"/>
      <media-object encoding="base64"><![CDATA[/9j/4AAQ[...snip...]P4Vm9zOR//Z=]]></media-object>
      <media.caption>What up</media.caption>
    </media>
</mediafiles>
Run Code Online (Sandbox Code Playgroud)

以及像这样处理的代码:

var xd = new XmlDocument();
xd.Load(filename);
var nodes = xd.GetElementsByTagName("media");

foreach (XmlNode node in nodes)
        {
            var mediaObjectNode = node.SelectSingleNode("media-object");
            //The line below is where the errors occur
            byte[] imageBytes = Convert.FromBase64String(mediaObjectNode.InnerText);
            //Do stuff with the bytearray to save the image
        }
Run Code Online (Sandbox Code Playgroud)

xml数据来自企业报纸系统,所以我很确定文件是正确的 - 我必须有一些处理方式,这是错误的.也许编码有问题?

我已经尝试写出mediaObjectNode.InnerText的内容,它是base64编码的数据 - 所以导航xml-doc不是问题.

我一直在谷歌搜索,binging,stackoverflowing和哭 - 并找不到解决方案......帮助!

编辑:

添加了一个实际的示例文件(和一个赏金).请注意,可下载文件的架构有点不同,因为我在上面的示例中简化了它,删除了不相关的东西......

Oli*_*ver 9

对于第一次拍摄我没有使用任何编程语言,只有Notepad ++

我在其中打开了xml文件,并将原始base64内容复制并粘贴到一个新文件中(没有方括号).

之后我选择了所有东西(Strg-A)并使用了Extensions选项 - Mime Tools - Base64 decode.这引发了关于错误文本长度的错误(必须是mod 4).所以我在末尾添加了两个等号('=')作为占位符以获得正确的长度.

另一次重试并成功解码为'某事'.只需将文件保存为.jpg,它就像任何图片查看器中的魅力一样打开.

所以我想说,你得到的数据有问题.他们只是在最后没有正确数量的等号来填补一些可以分成4个包的标志.

'简单'的方法是添加等号直到解码不会引发错误.更好的方法是计算字符数(减去CR/LF!)并在一步中添加所需的字符.

进一步调查

对转换函数进行一些编码和读取之后,问题是从生产者处错误地附加了等号.Notepad ++没有大量等号的问题,但MS的转换功能仅适用于零,一或两个符号.因此,如果您填写已存在的附加等号,您也会收到错误!为了让这个该死的东西工作,你必须切断所有现有的标志,计算需要多少,然后再添加它们.

只是为了赏金,这是我的代码(不是绝对完美,但足以获得一个好的起点):;-)

    static void Main(string[] args)
    {
        var elements = XElement
            .Load("test.xml")
            .XPathSelectElements("//media/media-object[@encoding='base64']");
        foreach (XElement element in elements)
        {
            var image = AnotherDecode64(element.Value);
        }
    }

    static byte[] AnotherDecode64(string base64Decoded)
    {
        string temp = base64Decoded.TrimEnd('=');
        int asciiChars = temp.Length - temp.Count(c => Char.IsWhiteSpace(c));
        switch (asciiChars % 4)
        {
            case 1:
                //This would always produce an exception!!
                //Regardless what (or what not) you attach to your string!
                //Better would be some kind of throw new Exception()
                return new byte[0];
            case 0:
                asciiChars = 0;
                break;
            case 2:
                asciiChars = 2;
                break;
            case 3:
                asciiChars = 1;
                break;
        }
        temp += new String('=', asciiChars);

        return Convert.FromBase64String(temp);
    }
Run Code Online (Sandbox Code Playgroud)