C#:解码Base64字符串不返回完整结果/ gibberisch

时间:2019-04-17 12:59:29

标签: c# .net base64

我们有a base64 encoded string被保存在数据库中。 (由此产生的结果仍然需要使用bzip2进行解码,但这是另一个问题。) 但是,当尝试使用C#进行转换时,我们会遇到一些问题。

        // get base 64 string from file
        string base64String = File.ReadAllText(@"D:\bzip2\base64text.txt", Encoding.UTF8);

        // decode from base64
        var largeCompressedTextAsBytes = Convert.FromBase64String(base64String);

        // convert to string
        var decodedString = Encoding.UTF8.GetString(largeCompressedTextAsBytes);
  • 首先,我们认为我们必须删除第一部分才能进行转换:
  

= base64起始行= 73 size = 142698 crc =

  • 接下来,我们得到一个结果,但是它太小了(而且全是乱码,但这又可能是因为使用bzip2进行了进一步的编码)
  

oW�k__i�ۍ��ֶӽ^k�MZ�V�bzip2,7,16813,16573,16672,16636,15710,14413,7264,BZh61AY&SY�de。

  • 我们尝试从文本中删除换行符(无济于事)text.Replace(Environment.NewLine, "");

这里有人有想法吗?

谢谢

选择

1 个答案:

答案 0 :(得分:2)

数据的第一行实际上是标题:

=base64begin line=73 size=142698 crc=1e0db1eda49fad0c242c2da2071ea521501a91ad

其余为base64。将base64转换为二进制后,您将得到一些文本:

bzip2,7,16813,16573,16672,16636,15710,14413,7264,

...,然后是bzip2文件。我不知道这个“标题”数据是什么,但是将其删除后,可以使用bunzip2提取其余数据。结果是一个包含一些图像的RTF文件。

接下来的步骤应该是获取有关在数据库中存储数据的内容以及准确是什么步骤的更多信息。它们似乎是:

  • 压缩文件
  • 添加以“ bzip2”开头的“标头”前缀
  • 将结果转换为base64
  • 添加另一个带有CRC和长度的“标头”前缀
  • 存储结果文本

您应该尝试找出所有这些步骤的确切细节,以便您可以撤消它们,并在执行过程中执行所有检查(例如CRC检查)。

这是一个完整的程序,可以从您提供的样本中提取文件。我已经在“内部”标头表格中进行了猜测,但您应该真正尝试找出创建标头的原因,以便验证我的假设。

using SharpCompress.Compressors.BZip2;
using System;
using System.IO;
using System.Text;

class Program
{
    static void Main(string[] args)
    {
        string base64;
        using (var reader = File.OpenText(args[0]))
        {
            // Skip the first line, which has some header information
            // TODO: Use it instead, to validate the rest of the data.
            reader.ReadLine();
            base64 = reader.ReadToEnd();
        }

        byte[] bytes = Convert.FromBase64String(base64);

        int startOfBody = FindStartOfBody(bytes);
        using (var input = new MemoryStream(bytes, startOfBody, bytes.Length - startOfBody))
        {
            using (var bzip2 = new BZip2Stream(input, SharpCompress.Compressors.CompressionMode.Decompress, true))
            {
                using (var output = File.OpenWrite(args[1]))
                {
                    bzip2.CopyTo(output);
                }
            }
        }
    }

    private static int FindStartOfBody(byte[] bytes)
    {
        // The file starts with a "header" of an unknown format, which we need to
        // skip. It looks like the format *might* be a sequence of comma-separated values
        // - Name of some kind (BZIP2)
        // - Number of further values
        // - The remaining values
        // That's what this code does.
        int offset = 0;
        // Skip the name
        GetNextHeaderValue(bytes, ref offset);
        // Find out how many more values there are
        string valueCountText = GetNextHeaderValue(bytes, ref offset);
        int valueCount = int.Parse(valueCountText);
        // Skip them
        for (int i = 0; i < valueCount; i++)
        {
            GetNextHeaderValue(bytes, ref offset);
        }
        // We'll now be positioned at the end
        return offset;
    }

    private static string GetNextHeaderValue(byte[] bytes, ref int offset)
    {
        StringBuilder builder = new StringBuilder();
        // TODO: Validation that we're not going past the end of the data...
        // We assume all header data is ASCII.
        for (; bytes[offset] != ','; offset++)
        {
            builder.Append((char) bytes[offset]);
        }
        // Move the offset past the comma
        offset++;
        return builder.ToString();
    }
}