除了 byteArray 为空之外,是否有任何byte[]
组合会导致此操作失败?
var myString = Convert.ToBase64String(byteArray);
我在想这样的事情...以字节零开头或结尾(空? 空byte[]
? 一个很大的byte[]
? 一些在 Base64 中没有意义的字节序列? 我的问题是未知的未知数。
是否有任何字节[]的组合会导致失败
byte[] byteArray = null;
var myString = Convert.ToBase64String(byteArray);
// NullArgumentException.
除了字节数组为空?
不。
以字节零开头或结尾(空?
以 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
-wise 您使用的Convert.ToBase64String
重载仅抛出ArgumentNullException
(当其参数inArray
为 null 时)。
任何可以表示为二进制的东西都可以进行 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;
}
}
}