using System; using System.Text; namespace Admin.Core.Common { public sealed class Base32Helper { // the valid chars for the encoding private static string ValidChars = "QAZ2WSX3" + "EDC4RFV5" + "TGB6YHN7" + "UJM8K9LP"; /// /// Converts an array of bytes to a Base32-k string. /// public static string ToString(byte[] bytes) { StringBuilder sb = new StringBuilder(); // holds the base32 chars byte index; int hi = 5; int currentByte = 0; while (currentByte < bytes.Length) { // do we need to use the next byte? if (hi > 8) { // get the last piece from the current byte, shift it to the right // and increment the byte counter index = (byte)(bytes[currentByte++] >> (hi - 5)); if (currentByte != bytes.Length) { // if we are not at the end, get the first piece from // the next byte, clear it and shift it to the left index = (byte)(((byte)(bytes[currentByte] << (16 - hi)) >> 3) | index); } hi -= 3; } else if (hi == 8) { index = (byte)(bytes[currentByte++] >> 3); hi -= 3; } else { // simply get the stuff from the current byte index = (byte)((byte)(bytes[currentByte] << (8 - hi)) >> 3); hi += 5; } sb.Append(ValidChars[index]); } return sb.ToString(); } /// /// Converts a Base32-k string into an array of bytes. /// /// /// Input string s contains invalid Base32-k characters. /// public static byte[] FromBase32String(string str) { int numBytes = str.Length * 5 / 8; byte[] bytes = new Byte[numBytes]; // all UPPERCASE chars str = str.ToUpper(); int bit_buffer; int currentCharIndex; int bits_in_buffer; if (str.Length < 3) { bytes[0] = (byte)(ValidChars.IndexOf(str[0]) | ValidChars.IndexOf(str[1]) << 5); return bytes; } bit_buffer = (ValidChars.IndexOf(str[0]) | ValidChars.IndexOf(str[1]) << 5); bits_in_buffer = 10; currentCharIndex = 2; for (int i = 0; i < bytes.Length; i++) { bytes[i] = (byte)bit_buffer; bit_buffer >>= 8; bits_in_buffer -= 8; while (bits_in_buffer < 8 && currentCharIndex < str.Length) { bit_buffer |= ValidChars.IndexOf(str[currentCharIndex++]) << bits_in_buffer; bits_in_buffer += 5; } } return bytes; } } }