如何可靠地正则表达Base64String

时间:2016-10-27 19:02:09

标签: c# regex binaryfiles

所以基本上我正在编写一个在二进制文件中查找PNG文件的应用程序。它通过将文件中的整个二进制文件读入一个字节数组,然后使用Convert.ToBase64String方法将其转换为字符串,然后使用匹配PNG的头信息和结束块的正则表达式来查找图像。问题是使用 ToBase64String 方法根据字节数组的长度生成截然不同的输出,MSDN上的文档似乎没有详细说明。无论如何,这是我的意思的一个例子。

 byte[] somebytes = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };

 Console.WriteLine(Convert.ToBase64String(somebytes));

这种情况下的输出现在是“AQIDBAUGBwg =”,如果我跳过一个字节......

 byte[] somebytes = new byte[] { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };

 somebytes = somebytes.Skip(1).ToArray();

 Console.WriteLine(Convert.ToBase64String(somebytes));

输出现在是“AgMEBQYHCA ==”,因此几乎每个字符都与前一个例子有所不同。

所以我绝望地在这里使用错误的路径重新编写二进制文件或者是否有方法(可能通过填充?)我可以保证这些转换更加一致吗?

更新 基于我收集的反馈,似乎我应该离开Regex解决方案并手动自己手动搜索开始和结束字节序列。不知道为什么我被投票,因为我只想了解为什么我的其他解决方案确实有效,而且似乎没有关于这个主题的任何其他帖子。无论如何,感谢大家的快速反馈。我将发布用于查找图像的算法,以防万一我可以从中受益。

2 个答案:

答案 0 :(得分:0)

您在评论中确认您正在尝试从C#结构化文件(EXE或DLL)中提取资源。你可以使用反射方法将它们拉出来:GetManifestResourceStream,GetManifestResourceNames,GetManifestResourceInfo是一个很好的起点。

答案 1 :(得分:0)

正如我所承诺的那样,我写的逻辑是为了找到二进制中的图像,如果它可以帮助别人。但是,我最终可能会使用 SledgeHammers 方法,但对我而言,我也能够使用此方法处理它。

public class BinarySearch
{
    public static IEnumerable<byte[]> Match(byte[] source, byte[] beginningSequence, byte[] endSequence)
    {
        int index = 0;

        IList<byte[]> matches = new List<byte[]>();

        while (index < source.Length)
        {
            var startIndex = FindSequence(source, beginningSequence, index);

            if (startIndex >= 0)
            {
                var endIndex = FindSequence(source, endSequence, startIndex + beginningSequence.Length);

                if (endIndex >= 0)
                {
                    var length = (endIndex - startIndex) + endSequence.Length;
                    var buffer = new byte[length];

                    Array.Copy(source, startIndex, buffer, 0, length);

                    matches.Add(buffer);

                    index = endIndex + endSequence.Length;
                }
                else
                {
                    index = source.Length;
                }
            }
            else
            {
                index = source.Length;
            }
        }

        return matches;
    }

    private static int FindSequence(byte[] bytes, byte[] sequence, int startIndex = 0)
    {
        int currentIndex = startIndex;
        int sequenceIndex = 0;
        bool found = false;

        while (!found && currentIndex < bytes.Length)
        {
            if (bytes[currentIndex] == sequence[sequenceIndex])
            {
                if (sequenceIndex == (sequence.Length - 1))
                {
                    found = true;
                }
                else
                {
                    sequenceIndex++;
                }
            }
            else
            {
                currentIndex -= sequenceIndex;
                sequenceIndex = 0;
            }

            currentIndex++;
        }

        return found ? (currentIndex - sequence.Length) : -1;
    }
}

以下是PNG文件的使用示例。

var imageHeaderStart = new byte[] { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00 };

var imageEOF = new byte[] { 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82 };

var matches = BinarySearch.Match(binaryData, imageHeaderStart, imageEOF);

如果有人对我的“完整”实施感兴趣,我会在Github项目完成后添加一个链接。