【问题标题】:Try to Read Base64 from Content fails尝试从内容中读取 Base64 失败
【发布时间】:2020-03-15 22:27:11
【问题描述】:

我尝试从图像中读取 base64 编码文件。 我解析了文档并提取了 base64 内容,但是当我尝试将信息解码为字节数组时出现错误,我提供的 base64 字符串已损坏。 我尝试从 JPEG 中提取 base64 编码的音频文件。

我检查了字符串,没有找到问题,也许你们可以帮助我?

FormatException 发生在:

Convert.FromBase64String(base64AudioString);

附上代码:

string path = @"D:\Projects\200308 - ImageReader\ConsoleApp1\";

// --- Read JPG ---
byte[] jpegBytes = File.ReadAllBytes(path + "IMG_20190905_132110.vr.jpg");
var asString = Encoding.Unicode.GetString(jpegBytes);

// --- Check for GAUDIO-Infos ---
var start = asString.IndexOf("GAudio:Data=") + 13; // asString.IndexOf("<x:xmpmeta");
var end = asString.IndexOf("\"", start); // asString.IndexOf("</x:xmpmeta>");

if(start != -1 && end != -1)
{
    // Parse Base64 Part
    string base64AudioString = asString.Substring(start, end - start);
    //base64AudioString = base64AudioString.Replace('-', '+').Replace('_', '/').PadRight(4 * ((base64AudioString.Length + 3) / 4), '='); // Validate
    //File.WriteAllText(path + "IMG_20190905_132110.vr.jpg.base64string", base64AudioString); // Export string into file

    // Write Byte Array
    byte[] base64ByteArray = Convert.FromBase64String(base64AudioString);
    File.WriteAllBytes(path + "IMG_20190905_132110.vr.jpg.gaudio", base64ByteArray);
}

这也是我尝试解析的示例文件: https://drive.google.com/open?id=1n7dE5U0YBRKiQzH4TovT2acSubuLt_u2

编辑:我发现编码需要是: Encoding.Default.GetString(jpegBytes); // 不编码 ASCII

【问题讨论】:

  • 你看过失败的字符串的内容了吗?它实际上可能不是 Base64,例如长度不正确(4 的倍数)或包含无效字符。
  • 首先我必须承认我对这种音频格式一无所知。来自您这边的更多信息会有所帮助,我没有找到任何东西。但是我查看了该文件:当您在记事本++ 中打开该 jpeg 并搜索GAudio:Data= 时,您会注意到首先有一些base64 数据,然后是ÿáÿÅhttp://ns.adobe.com/xmp/extension/ 2A1FDC3384D267CA2F17CF49E1B3317F h¯Ø Ì`,然后是更多base64 数据。这就是为什么你不能只解码开始和结束之间的整个部分。但是由于我不知道那种格式,所以我不知道要采取什么并将其放入文件中以获得可播放的音频文件。
  • 大家好,感谢您的回复。该 URL 可能是您正确的损坏。我从谷歌文档中获取我的信息,因为这个文件是由谷歌纸板相机应用程序创建的,它在文件中放入了一些更多信息,包括音频。这是文档的链接。在页面末尾,您将找到我喜欢解析的信息示例:developers.google.com/vr/reference/…
  • 音频一般保存为M4A,图像中定义了Mime类型,稍后我会在提取数据时考虑到设置正确的文件扩展名。我有一个可用的 base64 提取作为我用不同工具提取的比较。当我在家时,我会将其上传到帖子中。到目前为止谢谢!
  • @Zero:我找到了一种验证方法,可以使用:base64AudioString = base64AudioString.Replace('-', '+').Replace('_', '/' ).PadRight(4 * ((base64AudioString.Length + 3) / 4), '=');

标签: c# base64


【解决方案1】:

您快到了,但您需要进行一些较小的更正。

  • 而不是

    var asString = Encoding.Unicode.GetString(jpegBytes);
    

    你必须使用 ASCII 编码:

    var asString = Encoding.ASCII.GetString(jpegBytes);
    

    这就是为什么你会得到很多亚洲字符而不是 base64 代码的不可读输出的主要原因。

  • 那么你必须搜索结尾为:

    var end = asString.IndexOf("</rdf:RDF>", start) -4;
    
  • 至少您的示例图片包含这样的字符串:

    ÿáÿÅhttp://ns.adobe.com/xmp/extension/ 2A1FDC3384D267CA2F17CF49E1B3317F h¯Ø Ì
    

    混合在base64代码下(出现7次!),需要去除:

            var rubbish = "http://";
            var indexRubbish = base64AudioString.IndexOf(rubbish);
            while (indexRubbish >= 0)
            {
                base64AudioString = base64AudioString.Remove(indexRubbish - 4, 79);
                indexRubbish = base64AudioString.IndexOf(rubbish);
            }
    
  • 最后你需要填充(你的代码中已经有这个但被注释掉了)

            base64AudioString = base64AudioString.PadRight(4 * ((base64AudioString.Length + 3) / 4), '='); 
    

那么完整的代码是:

string path = @"D:\Projects\200308 - ImageReader\ConsoleApp1\";

// --- Read JPG ---
byte[] jpegBytes = File.ReadAllBytes(path + "IMG_20190905_132110.vr.jpg");
var asString = Encoding.ASCII.GetString(jpegBytes);

// --- Check for GAUDIO-Infos ---
var start = asString.IndexOf("GAudio:Data=") + 13;
var end = asString.IndexOf("</rdf:RDF>", start) -4;

if (start != -1 && end != -1)
{
    // Parse Base64 Part
    string base64AudioString = asString.Substring(start, end - start);
    var rubbish = "http://";
    var indexRubbish = base64AudioString.IndexOf(rubbish);
    while (indexRubbish >= 0)
    {
        base64AudioString = base64AudioString.Remove(indexRubbish - 4, 79);
        indexRubbish = base64AudioString.IndexOf(rubbish);
    }

    base64AudioString = base64AudioString.PadRight(4 * ((base64AudioString.Length + 3) / 4), '='); // Validate

    byte[] base64ByteArray = Convert.FromBase64String(base64AudioString);
    File.WriteAllBytes(path + "IMG_20190905_132110.vr.mp3", base64ByteArray);
}

结果是一个可播放的 mp3 文件。

【讨论】:

  • 非常感谢 jps。你让我今天一整天都感觉很好。就是这样!并感谢您的逐步解释。我现在用另一个文件尝试了它,需要在末尾为字符串“/”添加一个额外的删除。所以我想我会继续添加更多的垃圾检查和一个可靠的导出的矿类型解释。
  • 顺便说一句。 notepad++ 的提示非常好。我以前使用过 sublime,但它已经解释了很多,所以我无法弄清楚你找到的东西。于是我安装了notepad++,可以正常看到格式了。
  • 不客气。是一个非常有趣的“难题”来解决;-) NP++ 对开发人员来说是一个非常有用的工具。
  • @StephanSch 我唯一想知道的是所有这些 http:// 链接来自哪里,破坏了 base64 代码?
  • 好点。我直接从我的 Google 照片帐户下载了这些图像。我会将文件与智能手机上记录的文件进行比较。也许是从网站上下载的破坏了它。
猜你喜欢
  • 2015-08-26
  • 1970-01-01
  • 2022-12-31
  • 1970-01-01
  • 2017-05-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-02
相关资源
最近更新 更多