I've written the following unsafe C# method to convert a byte array to Base64 encoding. It works, but it runs at a significantly slower rate than the built-in Convert.ToBase64String
method.
public static unsafe string From(byte[] data)
{
int div = data.Length / 3;
int mod = data.Length % 3;
int length = data.Length;
int b64Length = div * 4 + (mod == 0 ? 0 : 4);
int c = 0;
char[] r = new char[b64Length];
fixed (char* tblPointer = base64Table)
fixed (char* rPointer = r)
fixed (byte* dPointer = data)
{
for (int i = 0; i < div * 3; i += 3)
{
rPointer[c] = tblPointer[(dPointer[i] & 0xfc) >> 2];
rPointer[c + 1] = tblPointer[((dPointer[i] & 0x03) << 4) | ((dPointer[i + 1] & 0xf0) >> 4)];
rPointer[c + 2] = tblPointer[((dPointer[i + 1] & 0x0f) << 2) | ((dPointer[i + 2] & 0xc0) >> 6)];
rPointer[c + 3] = tblPointer[((dPointer[i + 2]) & 0x3f)];
c += 4;
}
switch (mod)
{
case 1:
rPointer[c] = tblPointer[(dPointer[length - 1] & 0xfc) >> 2];
rPointer[c + 1] = tblPointer[((dPointer[length - 1] & 0x03) << 4)];
rPointer[c + 2] = '=';
rPointer[c + 3] = '=';
c += 4;
break;
case 2:
rPointer[c] = tblPointer[(dPointer[length - 2] & 0xfc) >> 2];
rPointer[c + 1] = tblPointer[((dPointer[length - 2] & 0x03) << 4) | ((dPointer[length - 1] & 0xf0) >> 4)];
rPointer[c + 2] = tblPointer[((dPointer[length - 1] & 0x0f) << 2)];
rPointer[c + 3] = '=';
c += 4;
break;
}
}
return new string(r);
}
I looked at the Reference Source for the .NET method and found that my code is very very similar already. Is there something I'm missing or is there some sort of optimization to the built in method I don't know about?
The variable base64Table
in the code is simply a char[]
with the relevant base64 characters.
The results being 31 Ticks for the built in method and 2230 Ticks for my method, measured with the System.Diagnostics.Stopwatch
class.