3

除了 byteArray 为空之外,是否有任何组合byte[]会导致此失败?

var myString = Convert.ToBase64String(byteArray);

我在想……以字节零(null?)开头或结尾。一个空的byte[]?一个很大的byte[]?一些在 Base64 中没有意义的字节序列?我的问题是未知的未知数。

4

3 回答 3

4

是否有任何字节 [] 组合会导致此失败

byte[] byteArray = null;
var myString = Convert.ToBase64String(byteArray);
// NullArgumentException.

除了 byteArray 为空?

没有。

以字节零开始或结束(空?)

以 0 结尾:

var byteArray = new byte[] {255, 255, 0};
var myString = Convert.ToBase64String(byteArray);
Console.WriteLine(myString); // +voA

领先0:

var byteArray = new byte[] {0, 250, 250};
var myString = Convert.ToBase64String(byteArray);
Console.WriteLine(myString); // APr6

顺便一提...

var byteArray = new byte[] {250, 250};
var myString = Convert.ToBase64String(byteArray);
Console.WriteLine(myString); // +vo=

不,这不仅仅是忽略 0。

一个空字节[]?

var byteArray = new byte[] {};
var myString = Convert.ToBase64String(byteArray);
Console.WriteLine(myString.Length); // 0

空字符串。

一个非常大的字节[]?

恩...

var byteArray = new byte[int.MaxValue]; // OutOfMemoryException

唔...

var byteArray = new byte[int.MaxValue / 8];
var myString = Convert.ToBase64String(byteArray);
Console.WriteLine(myString.Length); // 357913940

它活了下来。

一些在 Base64 中没有意义的字节序列?

不存在这样的事情。您将输入作为二进制(基数 2),将基数转换为基数 64,并遵循表示标准。


我的问题是未知的未知数。

一般来说,坚持文档,不要尝试做没有文档的事情。

我想平台中可能存在错误。有一些错误,ToBase64String我不知道。但是 - 通常 - 修复它们或解决它们不是您的责任(有时您必须这样做)。如果你碰巧遇到一个,报告它。

有错误的事情是它们在被发现之前都是未知的未知数。你可以试试看这里这里。除此之外,如果我不认识他们,我怎么能给你指点他们呢?

哦,你想找虫子吗?好吧,测试(就像我为这个答案所做的那样),并查看源代码(参考源代码.NET Core)。嘿,他们正在使用ReadOnlySpan,我想这就是为什么它没有被大阵列炸毁的原因。

于 2019-08-26T19:56:04.460 回答
2

除了 byteArray 为空之外,是否存在任何会导致失败的 byte[] 组合?

文档所述:不。Exception-明智的Convert.ToBase64String你使用的重载只会抛出ArgumentNullException(当它的参数inArray为空时)。

于 2019-08-26T19:41:54.757 回答
1

任何可以表示为二进制的东西都可以进行 base64 编码。这是因为该算法处理数据的二进制表示,而不是您使用它的任何表示。因此,可以对任何二进制字符串进行编码,但是当您解码时,您必须准确了解结果类型。

创建自己的 base64 编码器和解码器将是一个值得练习的练习,或者是 kata。我在回答中包含了我自己的 base64 编码类以用作参考。它远不是最有效的方法,而且可能比 .NET 的本机实现慢得多,而且它只解码回字符串。但我认为从初学者的角度来看,我的可能更容易阅读。

public class Base64Utility
{
    List<char> characterMap = new List<char>()
    {
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
        'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
        '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
        '+', '/'
    };

    public string Base64Encode(string source)
    {
        string result = string.Empty;
        int octetsMissing = 0;
        string byteString = string.Empty;

        byte[] bytes = new byte[source.Length];
        int[] base10Integers = new int[source.Length];

        for (int i = 0; i < source.Length; i++)
        {
            byte b = Convert.ToByte(source[i]);
            bytes[i] = (b);
            base10Integers[i] = Convert.ToInt32(bytes[i].ToString(), 10);
            byteString += Convert.ToString(bytes[i], 2).PadLeft(8, '0');
        }

        for (int byteIndex = 0; byteIndex < byteString.Length;)
        {
            int span = byteString.Length - byteIndex >= 6
                ? 6
                : byteString.Length - byteIndex;

            string subString = byteString.Substring(byteIndex, span);

            if (subString.Length < 6)
            {
                octetsMissing = (6 - subString.Length) / 2;
                for (int i = subString.Length; i < 6; i++)
                {
                    subString += '0';
                }
            }

            int index = Convert.ToInt32(subString, 2);

            result += characterMap[index];

            byteIndex += span;
        }

        for (int i = 0; i < octetsMissing; i++)
        {
            result += '=';
        }
        return result;
    }

    public string Base64Decode(string source)
    {
        string result = string.Empty;

        int[] mappedSource = new int[source.Length];
        string[] mappedSourceAsBinary = new string[source.Length];

        for (int i = 0; i < source.Length; i++)
        {
            if(source[i] != '=')
            {
                mappedSource[i] = characterMap.IndexOf(source[i]);
                mappedSourceAsBinary[i] = Convert.ToString(mappedSource[i], 2);
            }

            if(mappedSourceAsBinary[i] != null)
            {
                if(mappedSourceAsBinary[i].Length < 6)
                {
                    for(int j = mappedSourceAsBinary[i].Length; j < 6; j++)
                    {
                        mappedSourceAsBinary[i] = '0' + mappedSourceAsBinary[i];
                    }
                }
            }
        }

        string temp = string.Empty;
        for(int i = 0; i < mappedSourceAsBinary.Length; i++)
        {
            temp += mappedSourceAsBinary[i];
        }

        string[] t = new string[temp.Length / 8];

        for (int i = 0; i < t.Length; i++)
        {
            t[i] = temp.Substring(8*i, 8);
            int res = Convert.ToInt32(t[i], 2);
            char resAscii = Encoding.ASCII.GetString(new byte[] { (byte)res })[0];
            result += resAscii;
        }

        return result;
    }

}
}
于 2019-08-26T19:46:23.860 回答