C #: Декодирование строки Base64 не возвращает полный результат / gibberisch - PullRequest
0 голосов
/ 17 апреля 2019

У нас есть строка в кодировке base64 , которая сохраняется в базе данных.(Результат от этого еще нужно декодировать с помощью 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);
  • Прежде всего, мы думаеммы должны удалить первую часть, чтобы он даже конвертировался:

= base64begin line = 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 Ответ

2 голосов
/ 17 апреля 2019

Первая строка ваших данных - это заголовок:

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

Остальное - base64. После преобразования этого base64 в двоичный файл вы получите текст:

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

... сопровождаемый файлом bzip2. Я не знаю, что это за данные "заголовка", но после их удаления остальное можно извлечь с помощью bunzip2. В результате получается файл RTF, содержащий несколько изображений.

Следующие шаги должны быть направлены на получение дополнительной информации о том, что хранит данные в базе данных, и точно каковы его шаги. Они выглядят так:

  • Сжать файл
  • Добавить префикс "header", начинающийся с "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();
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...