Base64Encoder
using System;
using System.IO;
namespace Org.BouncyCastle.Utilities.Encoders
{
public class Base64Encoder : IEncoder
{
protected readonly byte[] encodingTable = new byte[64] {
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
90,
97,
98,
99,
100,
101,
102,
103,
104,
105,
106,
107,
108,
109,
110,
111,
112,
113,
114,
115,
116,
117,
118,
119,
120,
121,
122,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
43,
47
};
protected byte padding = 61;
protected readonly byte[] decodingTable = new byte[128];
protected void InitialiseDecodingTable()
{
Arrays.Fill(decodingTable, byte.MaxValue);
for (int i = 0; i < encodingTable.Length; i++) {
decodingTable[encodingTable[i]] = (byte)i;
}
}
public Base64Encoder()
{
InitialiseDecodingTable();
}
public int Encode(byte[] inBuf, int inOff, int inLen, byte[] outBuf, int outOff)
{
int num = inOff;
int num2 = inOff + inLen - 2;
int num3 = outOff;
while (num < num2) {
uint num5 = inBuf[num++];
uint num7 = inBuf[num++];
uint num9 = inBuf[num++];
outBuf[num3++] = encodingTable[(num5 >> 2) & 63];
outBuf[num3++] = encodingTable[((num5 << 4) | (num7 >> 4)) & 63];
outBuf[num3++] = encodingTable[((num7 << 2) | (num9 >> 6)) & 63];
outBuf[num3++] = encodingTable[num9 & 63];
}
switch (inLen - (num - inOff)) {
case 1: {
uint num23 = inBuf[num++];
outBuf[num3++] = encodingTable[(num23 >> 2) & 63];
outBuf[num3++] = encodingTable[(num23 << 4) & 63];
outBuf[num3++] = padding;
outBuf[num3++] = padding;
break;
}
case 2: {
uint num15 = inBuf[num++];
uint num17 = inBuf[num++];
outBuf[num3++] = encodingTable[(num15 >> 2) & 63];
outBuf[num3++] = encodingTable[((num15 << 4) | (num17 >> 4)) & 63];
outBuf[num3++] = encodingTable[(num17 << 2) & 63];
outBuf[num3++] = padding;
break;
}
}
return num3 - outOff;
}
public int Encode(byte[] buf, int off, int len, Stream outStream)
{
if (len < 0)
return 0;
byte[] array = new byte[72];
int num2;
for (int num = len; num > 0; num -= num2) {
num2 = System.Math.Min(54, num);
int count = Encode(buf, off, num2, array, 0);
outStream.Write(array, 0, count);
off += num2;
}
return (len + 2) / 3 * 4;
}
private bool Ignore(char c)
{
if (c != '\n' && c != '\r' && c != '\t')
return c == ' ';
return true;
}
public int Decode(byte[] data, int off, int length, Stream outStream)
{
byte[] array = new byte[54];
int num = 0;
int num2 = 0;
int num3 = off + length;
while (num3 > off && Ignore((char)data[num3 - 1])) {
num3--;
}
int num4 = num3 - 4;
int num5;
for (num5 = NextI(data, off, num4); num5 < num4; num5 = NextI(data, num5, num4)) {
byte b = decodingTable[data[num5++]];
num5 = NextI(data, num5, num4);
byte b2 = decodingTable[data[num5++]];
num5 = NextI(data, num5, num4);
byte b3 = decodingTable[data[num5++]];
num5 = NextI(data, num5, num4);
byte b4 = decodingTable[data[num5++]];
if ((b | b2 | b3 | b4) >= 128)
throw new IOException("invalid characters encountered in base64 data");
array[num++] = (byte)((b << 2) | (b2 >> 4));
array[num++] = (byte)((b2 << 4) | (b3 >> 2));
array[num++] = (byte)((b3 << 6) | b4);
if (num == array.Length) {
outStream.Write(array, 0, num);
num = 0;
}
num2 += 3;
}
if (num > 0)
outStream.Write(array, 0, num);
int num13 = NextI(data, num5, num3);
int num14 = NextI(data, num13 + 1, num3);
int num15 = NextI(data, num14 + 1, num3);
int num16 = NextI(data, num15 + 1, num3);
return num2 + DecodeLastBlock(outStream, (char)data[num13], (char)data[num14], (char)data[num15], (char)data[num16]);
}
private int NextI(byte[] data, int i, int finish)
{
while (i < finish && Ignore((char)data[i])) {
i++;
}
return i;
}
public int DecodeString(string data, Stream outStream)
{
int num = 0;
int num2 = data.Length;
while (num2 > 0 && Ignore(data[num2 - 1])) {
num2--;
}
int num3 = num2 - 4;
int num4;
for (num4 = NextI(data, 0, num3); num4 < num3; num4 = NextI(data, num4, num3)) {
byte b = decodingTable[data[num4++]];
num4 = NextI(data, num4, num3);
byte b2 = decodingTable[data[num4++]];
num4 = NextI(data, num4, num3);
byte b3 = decodingTable[data[num4++]];
num4 = NextI(data, num4, num3);
byte b4 = decodingTable[data[num4++]];
if ((b | b2 | b3 | b4) >= 128)
throw new IOException("invalid characters encountered in base64 data");
outStream.WriteByte((byte)((b << 2) | (b2 >> 4)));
outStream.WriteByte((byte)((b2 << 4) | (b3 >> 2)));
outStream.WriteByte((byte)((b3 << 6) | b4));
num += 3;
}
return num + DecodeLastBlock(outStream, data[num2 - 4], data[num2 - 3], data[num2 - 2], data[num2 - 1]);
}
private int DecodeLastBlock(Stream outStream, char c1, char c2, char c3, char c4)
{
if (c3 == padding) {
if (c4 != padding)
throw new IOException("invalid characters encountered at end of base64 data");
byte b = decodingTable[c1];
byte b2 = decodingTable[c2];
if ((b | b2) >= 128)
throw new IOException("invalid characters encountered at end of base64 data");
outStream.WriteByte((byte)((b << 2) | (b2 >> 4)));
return 1;
}
if (c4 == padding) {
byte b3 = decodingTable[c1];
byte b4 = decodingTable[c2];
byte b5 = decodingTable[c3];
if ((b3 | b4 | b5) >= 128)
throw new IOException("invalid characters encountered at end of base64 data");
outStream.WriteByte((byte)((b3 << 2) | (b4 >> 4)));
outStream.WriteByte((byte)((b4 << 4) | (b5 >> 2)));
return 2;
}
byte b6 = decodingTable[c1];
byte b7 = decodingTable[c2];
byte b8 = decodingTable[c3];
byte b9 = decodingTable[c4];
if ((b6 | b7 | b8 | b9) >= 128)
throw new IOException("invalid characters encountered at end of base64 data");
outStream.WriteByte((byte)((b6 << 2) | (b7 >> 4)));
outStream.WriteByte((byte)((b7 << 4) | (b8 >> 2)));
outStream.WriteByte((byte)((b8 << 6) | b9));
return 3;
}
private int NextI(string data, int i, int finish)
{
while (i < finish && Ignore(data[i])) {
i++;
}
return i;
}
}
}