除了 byteArray 为空之外,是否有任何组合byte[]
会导致此失败?
var myString = Convert.ToBase64String(byteArray);
我在想……以字节零(null?)开头或结尾。一个空的byte[]
?一个很大的byte[]
?一些在 Base64 中没有意义的字节序列?我的问题是未知的未知数。
除了 byteArray 为空之外,是否有任何组合byte[]
会导致此失败?
var myString = Convert.ToBase64String(byteArray);
我在想……以字节零(null?)开头或结尾。一个空的byte[]
?一个很大的byte[]
?一些在 Base64 中没有意义的字节序列?我的问题是未知的未知数。
是否有任何字节 [] 组合会导致此失败
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
,我想这就是为什么它没有被大阵列炸毁的原因。
除了 byteArray 为空之外,是否存在任何会导致失败的 byte[] 组合?
如文档所述:不。Exception
-明智的Convert.ToBase64String
你使用的重载只会抛出ArgumentNullException
(当它的参数inArray
为空时)。
任何可以表示为二进制的东西都可以进行 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;
}
}
}