using System; using System.Collections.Generic; using System.Text; using System.Collections; namespace basic64 { public class Basic64 { private Hashtable hash = new Hashtable(); private Encoding encoding; private char[] dataMapping ={ 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/', '=' }; public Basic64(Encoding encoding) { InitTable(); this.encoding = encoding; } public Basic64() { InitTable(); this.encoding = Encoding.GetEncoding("gb2312"); } private void InitTable() { // A-Z 0-25 for (int i = 0; i <= 25; i++) { string letter = "" + Convert.ToChar('A' + i); hash.Add(letter, i); } for (int i = 26; i <= 51; i++) { string letter = "" + Convert.ToChar('a' + i - 26); hash.Add(letter, i); } for (int i = 52; i <= 61; i++) { hash.Add("" + (i - 52), i); } hash.Add("+", 62); hash.Add("/", 63); hash.Add("=", 64); } /// <summary> /// basic64编码 /// </summary> /// <param name="code"></param> /// <returns></returns> public string ToBase64(string code) { byte[] bytes = this.encoding.GetBytes(code); int size = (bytes.Length % 3 == 0) ? 3 : (bytes.Length % 3); byte[] buffer = new byte[bytes.Length + (3 - size)]; string ret = ""; Buffer.BlockCopy(bytes, 0, buffer, 0, bytes.Length); byte[] dBuffer = new byte[buffer.Length / 3 * 4]; int j = 0; for (int i = 0; i < buffer.Length / 3; i++) { int q = i * 3; dBuffer[j] = (byte)((buffer[q] >> 2) & 0x3f); dBuffer[++j] = (byte)((((buffer[q] << 6) >> 2) & 0x3f) | (((buffer[q + 1] >> 4)) & 0x0f)); dBuffer[++j] = (byte)(((buffer[q + 1] << 4 >> 2) & 0x3f) | ((buffer[q + 2] >> 6) & 0x03)); dBuffer[++j] = (byte)((buffer[q + 2] << 2 >> 2) & 0x3f); j++; } for (int i = 0; i < dBuffer.Length - (3 - size); i++) { ret += dataMapping[(int)dBuffer[i]] + ""; } if ((3 - size) > 0) { for (int i = 0; i < (3 - size); i++) ret += '='; } return ret; } /// <summary> /// basic64解码 /// </summary> /// <param name="code"></param> /// <returns></returns> public string FromBasic64(string code) { if (code.Length % 4 != 0) throw new Exception("不正确的Basic64编码长度!"); byte[] buffer = new byte[code.Length / 4 * 3]; int j = 0; int padCount = findPadStr(code); for (int i = 0; i < code.Length / 4; i++) { int q = i * 4; int _a = Convert.ToInt32(hash[code[q].ToString()]); int _b = Convert.ToInt32(hash[code[q + 1].ToString()]); int _c = Convert.ToInt32(hash[code[q + 2].ToString()]); int _d = Convert.ToInt32(hash[code[q + 3].ToString()]); string a = fill8bits(Convert.ToString(_a, 2)).Substring(2, 6); string b = fill8bits(Convert.ToString(_b, 2)).Substring(2, 6); string c = fill8bits(Convert.ToString(_c, 2)).Substring(2, 6); string d = fill8bits(Convert.ToString(_d, 2)).Substring(2, 6); buffer[j] = Convert.ToByte(a + b.Substring(0, 2), 2); buffer[++j] = Convert.ToByte(b.Substring(2, 4) + c.Substring(0, 4), 2); buffer[++j] = Convert.ToByte((c.Substring(4, 2) + d), 2); j++; } return this.encoding.GetString(buffer, 0, buffer.Length - padCount); } #region helper private string fill8bits(string str) { int len = str.Length; if (len < 8) { for (int i = 0; i < (8 - len); i++) str = "0" + str; } return str; } private int findPadStr(string code) { int j = 0; int len = code.Length; for (int i = 0; i < 3; i++) { if (code.Substring(len - i - 1, 1).Equals("=")) { j++; } } return j; } #endregion } }