什么会导致Base64解码抛出FormatException

时间:2018-10-30 21:00:40

标签: c# .net base64

我正在使用C#和.NET编码和解码base64字符串。以下是我的代码段:

Base64编码:

using (var stream = new MemoryStream())
        …...
    return Convert.ToBase64String(stream.ToArray());
}

Base64解码

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

我的代码在99%的时间内失败,但是有1%的机会成功。堆栈跟踪如下:

5xx错误返回:System.FormatException:输入不是有效的Base-64字符串,因为它包含非Base 64字符,两个以上的填充字符或填充字符中的非法字符。在System.Convert.FromBase64_ComputeResultLength(Char inputPtr,Int32 inputLength)在System.Convert.FromBase64CharPtr(Char * inputPtr,Int32 inputLength)在System.Convert.FromBase64String(String s)*

有人知道会导致base64解码失败的原因吗?我的编码和解码方法是对称的,我真的很困惑这个问题的根本原因是什么?

2 个答案:

答案 0 :(得分:0)

感谢您的所有答复。

事实证明,仍然存在一些Json格式的旧消息,这些消息以前无法传递,并在我们的系统中不断重试;但是,我们已经部署了接收方的新代码更改,并且接收方开始期望使用protobuf格式的消息,这在接收旧的Json格式消息时导致反序列化失败。

答案 1 :(得分:-2)

为了调试这样的问题,我通常编写一些测试或创建一个控制台应用程序来监视变量在函数之间的变化。

base64解码失败的可能情况之一是,如果解码器输入为HTMLEncoded。例如,当您将加密的字符串传递到URL时,这很常见。它会自动进行HTML编码,然后视编码输出的字符而定,有时无法解码,有时甚至无法解码。

这是一个简单的控制台应用程序来演示这一点。

class Program
{
    static void Main(string[] args)
    {
        string input = "testaa";

        TestEncodeDecode("test");
        TestEncodeDecode("testa");
        TestEncodeDecode("testaa");

        Console.ReadLine();
    }

    private static void TestEncodeDecode(string input)
    {
        string encoded = Encode(input);

        Console.WriteLine($"Encoded: {encoded}");

        string htmlEncoded = WebUtility.UrlEncode(encoded);

        Console.WriteLine($"htmlEncoded: {htmlEncoded}");

        string decodedString = Decode(htmlEncoded);

        Console.WriteLine($"Decoded: {decodedString}");

        Console.WriteLine();
    }

    private static string Decode(string htmlEncoded)
    {
        try
        {
            byte[] decoded = Convert.FromBase64String(htmlEncoded);

            return Encoding.ASCII.GetString(decoded);
        }
        catch(Exception)
        {
            return "Decoding failed";
        }
    }

    private static string Encode(string input)
    {
        byte[] bytes = Encoding.ASCII.GetBytes(input);
        using (var stream = new MemoryStream())
        {
            stream.Write(bytes);
            return Convert.ToBase64String(stream.ToArray());
        }
    }
}

您会看到前两个参数(“ test”和“ testa”)无法解码,但是第三个参数(“ testaa”)将成功。

为了“解决”此问题,请按如下所示更改Decode方法:

    private static string Decode(string htmlEncoded)
    {
        try
        {
            string regularEncodedString = WebUtility.UrlDecode(htmlEncoded);
            byte[] decoded = Convert.FromBase64String(regularEncodedString);

            return Encoding.ASCII.GetString(decoded);
        }
        catch(Exception)
        {
            return "Decoding failed";
        }
    }