You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

204 lines
7.4 KiB

namespace com.hitrust.trustpay.client
{
using System;
using System.Text;
public class Base64
{
private const int EIGHT_BIT_MASK = 0xff;
private const int LOWER_CASE_A_VALUE = 0x1a;
private int mIndex = 0;
private string mString;
private const int PLUS_VALUE = 0x3e;
private const int SIX_BIT_MASK = 0x3f;
private const int SLASH_VALUE = 0x3f;
private const int ZERO_VALUE = 0x34;
private int convertUnsignedByteToInt(byte b)
{
if (b >= 0)
{
return b;
}
return (0x100 + b);
}
public byte[] decode(string data)
{
this.mString = data;
this.mIndex = 0;
int mUsefulLength = 0;
int length = this.mString.Length;
for (int i = 0; i < length; i++)
{
if (this.isUsefulChar(this.mString[i]))
{
mUsefulLength++;
}
}
int byteArrayLength = (mUsefulLength * 3) / 4;
byte[] result = new byte[byteArrayLength];
int byteTriplet = 0;
int byteIndex = 0;
while ((byteIndex + 2) < byteArrayLength)
{
byteTriplet = this.mapCharToInt(this.NextUsefulChar) << 6;
byteTriplet |= this.mapCharToInt(this.NextUsefulChar);
byteTriplet = byteTriplet << 6;
byteTriplet |= this.mapCharToInt(this.NextUsefulChar);
byteTriplet = byteTriplet << 6;
byteTriplet |= this.mapCharToInt(this.NextUsefulChar);
result[byteIndex + 2] = (byte) (byteTriplet & 0xff);
byteTriplet = byteTriplet >> 8;
result[byteIndex + 1] = (byte) (byteTriplet & 0xff);
byteTriplet = byteTriplet >> 8;
result[byteIndex] = (byte) (byteTriplet & 0xff);
byteIndex += 3;
}
if (byteIndex == (byteArrayLength - 1))
{
byteTriplet = this.mapCharToInt(this.NextUsefulChar) << 6;
byteTriplet |= this.mapCharToInt(this.NextUsefulChar);
byteTriplet = byteTriplet >> 4;
result[byteIndex] = (byte) (byteTriplet & 0xff);
}
if (byteIndex == (byteArrayLength - 2))
{
byteTriplet = this.mapCharToInt(this.NextUsefulChar) << 6;
byteTriplet |= this.mapCharToInt(this.NextUsefulChar);
byteTriplet = byteTriplet << 6;
byteTriplet |= this.mapCharToInt(this.NextUsefulChar);
byteTriplet = byteTriplet >> 2;
result[byteIndex + 1] = (byte) (byteTriplet & 0xff);
byteTriplet = byteTriplet >> 8;
result[byteIndex] = (byte) (byteTriplet & 0xff);
}
return result;
}
public string encode(byte[] data)
{
byte b3;
byte b2;
byte b1;
int charCount = ((data.Length * 4) / 3) + 4;
StringBuilder result = new StringBuilder((charCount * 0x4d) / 0x4c);
int byteArrayLength = data.Length;
int byteArrayIndex = 0;
int byteTriplet = 0;
while (byteArrayIndex < (byteArrayLength - 2))
{
byteTriplet = this.convertUnsignedByteToInt(data[byteArrayIndex++]) << 8;
byteTriplet |= this.convertUnsignedByteToInt(data[byteArrayIndex++]);
byteTriplet = byteTriplet << 8;
byteTriplet |= this.convertUnsignedByteToInt(data[byteArrayIndex++]);
byte b4 = (byte) (0x3f & byteTriplet);
byteTriplet = byteTriplet >> 6;
b3 = (byte) (0x3f & byteTriplet);
byteTriplet = byteTriplet >> 6;
b2 = (byte) (0x3f & byteTriplet);
byteTriplet = byteTriplet >> 6;
b1 = (byte) (0x3f & byteTriplet);
result.Append(this.mapByteToChar(b1));
result.Append(this.mapByteToChar(b2));
result.Append(this.mapByteToChar(b3));
result.Append(this.mapByteToChar(b4));
}
if (byteArrayIndex == (byteArrayLength - 1))
{
byteTriplet = this.convertUnsignedByteToInt(data[byteArrayIndex++]) << 4;
b2 = (byte) (0x3f & byteTriplet);
byteTriplet = byteTriplet >> 6;
b1 = (byte) (0x3f & byteTriplet);
result.Append(this.mapByteToChar(b1));
result.Append(this.mapByteToChar(b2));
result.Append("==");
}
if (byteArrayIndex == (byteArrayLength - 2))
{
byteTriplet = this.convertUnsignedByteToInt(data[byteArrayIndex++]) << 8;
byteTriplet |= this.convertUnsignedByteToInt(data[byteArrayIndex++]);
byteTriplet = byteTriplet << 2;
b3 = (byte) (0x3f & byteTriplet);
byteTriplet = byteTriplet >> 6;
b2 = (byte) (0x3f & byteTriplet);
byteTriplet = byteTriplet >> 6;
b1 = (byte) (0x3f & byteTriplet);
result.Append(this.mapByteToChar(b1));
result.Append(this.mapByteToChar(b2));
result.Append(this.mapByteToChar(b3));
result.Append("=");
}
return result.ToString();
}
private bool isUsefulChar(char c)
{
return (((((c >= 'A') && (c <= 'Z')) || ((c >= 'a') && (c <= 'z'))) || (((c >= '0') && (c <= '9')) || (c == '+'))) || (c == '/'));
}
private char mapByteToChar(byte b)
{
if (b < 0x1a)
{
return (char) (0x41 + b);
}
if (b < 0x34)
{
return (char) (0x61 + (b - 0x1a));
}
if (b < 0x3e)
{
return (char) (0x30 + (b - 0x34));
}
if (b == 0x3e)
{
return '+';
}
if (b != 0x3f)
{
throw new ArgumentException("Byte " + b + " is not a valid Base64 value");
}
return '/';
}
private int mapCharToInt(char c)
{
if ((c >= 'A') && (c <= 'Z'))
{
return (c - 'A');
}
if ((c >= 'a') && (c <= 'z'))
{
return ((c - 'a') + 0x1a);
}
if ((c >= '0') && (c <= '9'))
{
return ((c - '0') + 0x34);
}
if (c == '+')
{
return 0x3e;
}
if (c != '/')
{
throw new ArgumentException(c + " is not a valid Base64 character.");
}
return 0x3f;
}
private char NextUsefulChar
{
get
{
char result = '_';
while (!this.isUsefulChar(result))
{
result = this.mString[this.mIndex++];
}
return result;
}
}
}
}