我们有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 =
oW�k__i�ۍ��ֶӽ^k�MZ�V�bzip2,7,16813,16573,16672,16636,15710,14413,7264,BZh61AY&SY�de。
text.Replace(Environment.NewLine, "");
这里有人有想法吗?
谢谢
选择
答案 0 :(得分:2)
数据的第一行实际上是标题:
=base64begin line=73 size=142698 crc=1e0db1eda49fad0c242c2da2071ea521501a91ad
其余为base64。将base64转换为二进制后,您将得到一些文本:
bzip2,7,16813,16573,16672,16636,15710,14413,7264,
...,然后是bzip2文件。我不知道这个“标题”数据是什么,但是将其删除后,可以使用bunzip2
提取其余数据。结果是一个包含一些图像的RTF文件。
接下来的步骤应该是获取有关在数据库中存储数据的内容以及准确是什么步骤的更多信息。它们似乎是:
您应该尝试找出所有这些步骤的确切细节,以便您可以撤消它们,并在执行过程中执行所有检查(例如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();
}
}