public static void Main()
byte[] x = { 97, 98, 99, 100};
byte[] x2 = s.FromBase62();
Console.WriteLine(Encoding.UTF8.GetString(x2));
public static class EncodingExtensions
private static string Base62CodingSpace = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
public static string ToBase62(this byte[] original)
StringBuilder sb = new StringBuilder();
BitStream stream = new BitStream(original);
byte[] read = new byte[1];
int length = stream.Read(read, 0, 6);
if ((int)(read[0] >> 3) == 0x1f)
sb.Append(Base62CodingSpace[61]);
stream.Seek(-1, SeekOrigin.Current);
else if ((int)(read[0] >> 3) == 0x1e)
sb.Append(Base62CodingSpace[60]);
stream.Seek(-1, SeekOrigin.Current);
sb.Append(Base62CodingSpace[(int)(read[0] >> 2)]);
sb.Append(Base62CodingSpace[(int)(read[0] >> (int)(8 - length))]);
public static byte[] FromBase62(this string base62)
BitStream stream = new BitStream(base62.Length * 6 / 8);
foreach (char c in base62)
int index = Base62CodingSpace.IndexOf(c);
if (count == base62.Length - 1)
int mod = (int)(stream.Position % 8);
throw new InvalidDataException("an extra character was found");
if ((index >> (8 - mod)) > 0)
throw new InvalidDataException("invalid ending character was found");
stream.Write(new byte[] { (byte)(index << mod) }, 0, 8 - mod);
stream.Write(new byte[] { 0xf0 }, 0, 5);
stream.Write(new byte[] { 0xf8 }, 0, 5);
stream.Write(new byte[] { (byte)index }, 2, 6);
byte[] result = new byte[stream.Position / 8];
stream.Seek(0, SeekOrigin.Begin);
stream.Read(result, 0, result.Length * 8);
public class BitStream : Stream
private byte[] Source { get; set; }
public BitStream(int capacity)
this.Source = new byte[capacity];
public BitStream(byte[] source)
public override bool CanRead
public override bool CanSeek
public override bool CanWrite
public override void Flush()
throw new NotImplementedException();
public override long Length
get { return Source.Length * 8; }
public override long Position { get; set; }
public override int Read(byte[] buffer, int offset, int count)
long tempPos = this.Position;
int readPosCount = 0, readPosMod = 0;
long posCount = tempPos >> 3;
int posMod = (int)(tempPos - ((tempPos >> 3) << 3));
while (tempPos < this.Position + offset + count && tempPos < this.Length)
if ((((int)this.Source[posCount]) & (0x1 << (7 - posMod))) != 0)
buffer[readPosCount] = (byte)((int)(buffer[readPosCount]) | (0x1 << (7 - readPosMod)));
buffer[readPosCount] = (byte)((int)(buffer[readPosCount]) & (0xffffffff - (0x1 << (7 - readPosMod))));
int bits = (int)(tempPos - this.Position - offset);
public override long Seek(long offset, SeekOrigin origin)
case (SeekOrigin.Current):
this.Position = this.Length + offset;
public override void SetLength(long value)
throw new NotImplementedException();
public override void Write(byte[] buffer, int offset, int count)
long tempPos = this.Position;
int readPosCount = offset >> 3, readPosMod = offset - ((offset >> 3) << 3);
long posCount = tempPos >> 3;
int posMod = (int)(tempPos - ((tempPos >> 3) << 3));
while (tempPos < this.Position + count && tempPos < this.Length)
if ((((int)buffer[readPosCount]) & (0x1 << (7 - readPosMod))) != 0)
this.Source[posCount] = (byte)((int)(this.Source[posCount]) | (0x1 << (7 - posMod)));
this.Source[posCount] = (byte)((int)(this.Source[posCount]) & (0xffffffff - (0x1 << (7 - posMod))));