c# base32

https://gist.github.com/BravoTango86/2a085185c3b9bd8383a1f956600e515f

 public static class Base32
    {
        private static readonly char[] _digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567".ToCharArray();
        private const int _mask = 31;
        private const int _shift = 5;

        private static int CharToInt(char c)
        {
            switch (c)
            {
                case ‘A‘: return 0;
                case ‘B‘: return 1;
                case ‘C‘: return 2;
                case ‘D‘: return 3;
                case ‘E‘: return 4;
                case ‘F‘: return 5;
                case ‘G‘: return 6;
                case ‘H‘: return 7;
                case ‘I‘: return 8;
                case ‘J‘: return 9;
                case ‘K‘: return 10;
                case ‘L‘: return 11;
                case ‘M‘: return 12;
                case ‘N‘: return 13;
                case ‘O‘: return 14;
                case ‘P‘: return 15;
                case ‘Q‘: return 16;
                case ‘R‘: return 17;
                case ‘S‘: return 18;
                case ‘T‘: return 19;
                case ‘U‘: return 20;
                case ‘V‘: return 21;
                case ‘W‘: return 22;
                case ‘X‘: return 23;
                case ‘Y‘: return 24;
                case ‘Z‘: return 25;
                case ‘2‘: return 26;
                case ‘3‘: return 27;
                case ‘4‘: return 28;
                case ‘5‘: return 29;
                case ‘6‘: return 30;
                case ‘7‘: return 31;
            }
            return -1;
        }

        public static byte[] FromBase32String(string encoded)
        {
            if (encoded == null)
                throw new ArgumentNullException(nameof(encoded));

            // Remove whitespace and padding. Note: the padding is used as hint 
            // to determine how many bits to decode from the last incomplete chunk
            // Also, canonicalize to all upper case
            encoded = encoded.Trim().TrimEnd(‘=‘).ToUpper();
            if (encoded.Length == 0)
                return new byte[0];

            var outLength = encoded.Length * _shift / 8;
            var result = new byte[outLength];
            var buffer = 0;
            var next = 0;
            var bitsLeft = 0;
            var charValue = 0;
            foreach (var c in encoded)
            {
                charValue = CharToInt(c);
                if (charValue < 0)
                    throw new FormatException("Illegal character: `" + c + "`");

                buffer <<= _shift;
                buffer |= charValue & _mask;
                bitsLeft += _shift;
                if (bitsLeft >= 8)
                {
                    result[next++] = (byte)(buffer >> (bitsLeft - 8));
                    bitsLeft -= 8;
                }
            }

            return result;
        }

        public static string ToBase32String(byte[] data, bool padOutput = false)
        {
            return ToBase32String(data, 0, data.Length, padOutput);
        }

        public static string ToBase32String(byte[] data, int offset, int length, bool padOutput = false)
        {
            if (data == null)
                throw new ArgumentNullException(nameof(data));

            if (offset < 0)
                throw new ArgumentOutOfRangeException(nameof(offset));

            if (length < 0)
                throw new ArgumentOutOfRangeException(nameof(length));

            if ((offset + length) > data.Length)
                throw new ArgumentOutOfRangeException();

            if (length == 0)
                return "";

            // SHIFT is the number of bits per output character, so the length of the
            // output is the length of the input multiplied by 8/SHIFT, rounded up.
            // The computation below will fail, so don‘t do it.
            if (length >= (1 << 28))
                throw new ArgumentOutOfRangeException(nameof(data));

            var outputLength = (length * 8 + _shift - 1) / _shift;
            var result = new StringBuilder(outputLength);

            var last = offset + length;
            int buffer = data[offset++];
            var bitsLeft = 8;
            while (bitsLeft > 0 || offset < last)
            {
                if (bitsLeft < _shift)
                {
                    if (offset < last)
                    {
                        buffer <<= 8;
                        buffer |= (data[offset++] & 0xff);
                        bitsLeft += 8;
                    }
                    else
                    {
                        int pad = _shift - bitsLeft;
                        buffer <<= pad;
                        bitsLeft += pad;
                    }
                }
                int index = _mask & (buffer >> (bitsLeft - _shift));
                bitsLeft -= _shift;
                result.Append(_digits[index]);
            }
            if (padOutput)
            {
                int padding = 8 - (result.Length % 8);
                if (padding > 0) result.Append(‘=‘, padding == 8 ? 0 : padding);
            }
            return result.ToString();
        }
    }
string result = Base32.ToBase32String(Encoding.UTF8.GetBytes("飞洒发飞洒发"));
string result2 = Encoding.UTF8.GetString(Base32.FromBase32String(result));
Console.WriteLine(result);
Console.WriteLine(result2);

c# base32

上一篇:C# Span 源码解读和应用实践


下一篇:GeolocationPositionErrorcode: 2 message: "Network location provider at 'https://www.googleapis.com/' : No response received."