update
This commit is contained in:
@@ -0,0 +1,203 @@
|
||||
using System.Text;
|
||||
|
||||
namespace BaseNcoding
|
||||
{
|
||||
public class Base32 : Base
|
||||
{
|
||||
public const string DefaultAlphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
public const char DefaultSpecial = '>';
|
||||
|
||||
public override bool HasSpecial => true;
|
||||
|
||||
public Base32(string alphabet = DefaultAlphabet, char special = DefaultSpecial, Encoding textEncoding = null)
|
||||
: base(32, alphabet, special, textEncoding)
|
||||
{
|
||||
}
|
||||
|
||||
public override string Encode(byte[] data)
|
||||
{
|
||||
int dataLength = data.Length;
|
||||
StringBuilder result = new StringBuilder((dataLength + 4) / 5 * 8);
|
||||
|
||||
byte x1, x2;
|
||||
int i;
|
||||
|
||||
int length5 = (dataLength / 5) * 5;
|
||||
for (i = 0; i < length5; i += 5)
|
||||
{
|
||||
x1 = data[i];
|
||||
result.Append(Alphabet[x1 >> 3]);
|
||||
|
||||
x2 = data[i + 1];
|
||||
result.Append(Alphabet[((x1 << 2) & 0x1C) | (x2 >> 6)]);
|
||||
result.Append(Alphabet[(x2 >> 1) & 0x1F]);
|
||||
|
||||
x1 = data[i + 2];
|
||||
result.Append(Alphabet[((x2 << 4) & 0x10) | (x1 >> 4)]);
|
||||
|
||||
x2 = data[i + 3];
|
||||
result.Append(Alphabet[((x1 << 1) & 0x1E) | (x2 >> 7)]);
|
||||
result.Append(Alphabet[(x2 >> 2) & 0x1F]);
|
||||
|
||||
x1 = data[i + 4];
|
||||
result.Append(Alphabet[((x2 << 3) & 0x18) | (x1 >> 5)]);
|
||||
result.Append(Alphabet[x1 & 0x1F]);
|
||||
}
|
||||
|
||||
switch (dataLength - length5)
|
||||
{
|
||||
case 1:
|
||||
x1 = data[i];
|
||||
result.Append(Alphabet[x1 >> 3]);
|
||||
result.Append(Alphabet[(x1 << 2) & 0x1C]);
|
||||
|
||||
result.Append(Special, 6);
|
||||
break;
|
||||
case 2:
|
||||
x1 = data[i];
|
||||
result.Append(Alphabet[x1 >> 3]);
|
||||
x2 = data[i + 1];
|
||||
result.Append(Alphabet[((x1 << 2) & 0x1C) | (x2 >> 6)]);
|
||||
result.Append(Alphabet[(x2 >> 1) & 0x1F]);
|
||||
result.Append(Alphabet[(x2 << 4) & 0x10]);
|
||||
|
||||
result.Append(Special, 4);
|
||||
break;
|
||||
case 3:
|
||||
x1 = data[i];
|
||||
result.Append(Alphabet[x1 >> 3]);
|
||||
x2 = data[i + 1];
|
||||
result.Append(Alphabet[((x1 << 2) & 0x1C) | (x2 >> 6)]);
|
||||
result.Append(Alphabet[(x2 >> 1) & 0x1F]);
|
||||
x1 = data[i + 2];
|
||||
result.Append(Alphabet[((x2 << 4) & 0x10) | (x1 >> 4)]);
|
||||
result.Append(Alphabet[(x1 << 1) & 0x1E]);
|
||||
|
||||
result.Append(Special, 3);
|
||||
break;
|
||||
case 4:
|
||||
x1 = data[i];
|
||||
result.Append(Alphabet[x1 >> 3]);
|
||||
x2 = data[i + 1];
|
||||
result.Append(Alphabet[((x1 << 2) & 0x1C) | (x2 >> 6)]);
|
||||
result.Append(Alphabet[(x2 >> 1) & 0x1F]);
|
||||
x1 = data[i + 2];
|
||||
result.Append(Alphabet[((x2 << 4) & 0x10) | (x1 >> 4)]);
|
||||
x2 = data[i + 3];
|
||||
result.Append(Alphabet[((x1 << 1) & 0x1E) | (x2 >> 7)]);
|
||||
result.Append(Alphabet[(x2 >> 2) & 0x1F]);
|
||||
result.Append(Alphabet[(x2 << 3) & 0x18]);
|
||||
|
||||
result.Append(Special);
|
||||
break;
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
public override byte[] Decode(string data)
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
if (string.IsNullOrEmpty(data))
|
||||
return new byte[0];
|
||||
|
||||
int additionalBytes = 0, diff = 0, tempLen = 0;
|
||||
|
||||
|
||||
int lastSpecialInd = data.Length;
|
||||
while (data[lastSpecialInd - 1] == Special)
|
||||
lastSpecialInd--;
|
||||
int tailLength = data.Length - lastSpecialInd;
|
||||
|
||||
switch (tailLength)
|
||||
{
|
||||
case 6:
|
||||
additionalBytes = 4;
|
||||
break;
|
||||
case 4:
|
||||
additionalBytes = 3;
|
||||
break;
|
||||
case 3:
|
||||
additionalBytes = 2;
|
||||
break;
|
||||
case 1:
|
||||
additionalBytes = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
diff = tailLength - additionalBytes;
|
||||
tailLength = additionalBytes;
|
||||
tempLen = data.Length - diff;
|
||||
|
||||
byte[] result = new byte[(tempLen + 7) / 8 * 5 - tailLength];
|
||||
int length5 = result.Length / 5 * 5;
|
||||
int x1, x2, x3, x4, x5, x6, x7, x8;
|
||||
|
||||
int i, srcInd = 0;
|
||||
for (i = 0; i < length5; i += 5)
|
||||
{
|
||||
x1 = InvAlphabet[data[srcInd++]];
|
||||
x2 = InvAlphabet[data[srcInd++]];
|
||||
x3 = InvAlphabet[data[srcInd++]];
|
||||
x4 = InvAlphabet[data[srcInd++]];
|
||||
x5 = InvAlphabet[data[srcInd++]];
|
||||
x6 = InvAlphabet[data[srcInd++]];
|
||||
x7 = InvAlphabet[data[srcInd++]];
|
||||
x8 = InvAlphabet[data[srcInd++]];
|
||||
|
||||
result[i] = (byte)((x1 << 3) | ((x2 >> 2) & 0x07));
|
||||
result[i + 1] = (byte)((x2 << 6) | ((x3 << 1) & 0x3E) | ((x4 >> 4) & 0x01));
|
||||
result[i + 2] = (byte)((x4 << 4) | ((x5 >> 1) & 0xF));
|
||||
result[i + 3] = (byte)((x5 << 7) | ((x6 << 2) & 0x7C) | ((x7 >> 3) & 0x03));
|
||||
result[i + 4] = (byte)((x7 << 5) | (x8 & 0x1F));
|
||||
}
|
||||
|
||||
switch (tailLength)
|
||||
{
|
||||
case 4:
|
||||
x1 = InvAlphabet[data[srcInd++]];
|
||||
x2 = InvAlphabet[data[srcInd++]];
|
||||
result[i] = (byte)((x1 << 3) | ((x2 >> 2) & 0x07));
|
||||
break;
|
||||
case 3:
|
||||
x1 = InvAlphabet[data[srcInd++]];
|
||||
x2 = InvAlphabet[data[srcInd++]];
|
||||
x3 = InvAlphabet[data[srcInd++]];
|
||||
x4 = InvAlphabet[data[srcInd++]];
|
||||
|
||||
result[i] = (byte)((x1 << 3) | ((x2 >> 2) & 0x07));
|
||||
result[i + 1] = (byte)((x2 << 6) | ((x3 << 1) & 0x3E) | ((x4 >> 4) & 0x01));
|
||||
break;
|
||||
case 2:
|
||||
x1 = InvAlphabet[data[srcInd++]];
|
||||
x2 = InvAlphabet[data[srcInd++]];
|
||||
x3 = InvAlphabet[data[srcInd++]];
|
||||
x4 = InvAlphabet[data[srcInd++]];
|
||||
x5 = InvAlphabet[data[srcInd++]];
|
||||
|
||||
result[i] = (byte)((x1 << 3) | ((x2 >> 2) & 0x07));
|
||||
result[i + 1] = (byte)((x2 << 6) | ((x3 << 1) & 0x3E) | ((x4 >> 4) & 0x01));
|
||||
result[i + 2] = (byte)((x4 << 4) | ((x5 >> 1) & 0xF));
|
||||
break;
|
||||
case 1:
|
||||
x1 = InvAlphabet[data[srcInd++]];
|
||||
x2 = InvAlphabet[data[srcInd++]];
|
||||
x3 = InvAlphabet[data[srcInd++]];
|
||||
x4 = InvAlphabet[data[srcInd++]];
|
||||
x5 = InvAlphabet[data[srcInd++]];
|
||||
x6 = InvAlphabet[data[srcInd++]];
|
||||
x7 = InvAlphabet[data[srcInd++]];
|
||||
|
||||
result[i] = (byte)((x1 << 3) | ((x2 >> 2) & 0x07));
|
||||
result[i + 1] = (byte)((x2 << 6) | ((x3 << 1) & 0x3E) | ((x4 >> 4) & 0x01));
|
||||
result[i + 2] = (byte)((x4 << 4) | ((x5 >> 1) & 0xF));
|
||||
result[i + 3] = (byte)((x5 << 7) | ((x6 << 2) & 0x7C) | ((x7 >> 3) & 0x03));
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user