同系列文章:
/* ---------------------------------------------------------- * 文件名称:Base64.cs * * 作者:秦建辉 * * MSN:splashcn@msn.com * QQ:36748897 * * 博客:http://www.firstsolver.com/wordpress/ * * 开发环境: * Visual Studio V2010 * .NET Framework 4 Client Profile * * 版本历史: * V1.1 2012年08月20日 * 改进解码算法,字符串中允许任意的空白字符、回车换行符、连字符 * * V1.0 2012年05月30日 * Base64编解码 * * 参考资料: * http://www.openssl.org/ ------------------------------------------------------------ */ using System; using System.IO; using System.Text; namespace Splash.Util { /// <summary> /// Base64 编解码 /// </summary> public static class Base64 { /// <summary> /// Base64编码字符集 /// </summary> private const String DATA_BIN2ASCII = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /// <summary> /// 将字节数组转换成 Base64 编码字符串 /// </summary> /// <param name="inArray">要转换的字节数组</param> /// <returns>转换后的 Base64 编码字符串</returns> public static String EncodeBase64String(Byte[] inArray) { if (inArray == null) return null; // 每3个字节转换成4个字符 Int32 Length = ((inArray.Length + 2) / 3) << 2; StringBuilder sb = new StringBuilder(Length); Int32 Index = 0; for (Int32 i = inArray.Length; i > 0; i -= 3) { if (i >= 3) { // 将3字节数据转换成4个ASCII字符 Byte b0 = inArray[Index++]; Byte b1 = inArray[Index++]; Byte b2 = inArray[Index++]; sb.Append(DATA_BIN2ASCII[b0 >> 2]); sb.Append(DATA_BIN2ASCII[((b0 << 4) | (b1 >> 4)) & 0x3F]); sb.Append(DATA_BIN2ASCII[((b1 << 2) | (b2 >> 6)) & 0x3F]); sb.Append(DATA_BIN2ASCII[b2 & 0x3F]); } else { Byte b0 = inArray[Index++]; Byte b1; if (i == 2) b1 = inArray[Index++]; else b1 = 0; sb.Append(DATA_BIN2ASCII[b0 >> 2]); sb.Append(DATA_BIN2ASCII[((b0 << 4) | (b1 >> 4)) & 0x3F]); if (i == 1) sb.Append('='); else sb.Append(DATA_BIN2ASCII[(b1 << 2) & 0x3F]); sb.Append('='); } } return sb.ToString(); } // private const Byte B64_ERROR = 0xFF; // 错误字符 // private const Byte B64_EOLN = 0xF0; // 换行\n // private const Byte B64_CR = 0xF1; // 回车\r // private const Byte B64_EOF = 0xF2; // 连字符- // private const Byte B64_WS = 0xE0; // 跳格或者空格(\t、space) private const Byte B64_NOT_BASE64 = 0xF3; // 空白字符、回车换行字符、连字符 /// <summary> /// Base64 编码字符对应的序号列表 /// </summary> private static readonly Byte[] DATA_ASCII2BIN = { 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xE0,0xF0,0xFF,0xFF,0xF1,0xFF,0xFF, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF, 0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x3E,0xFF,0xF2,0xFF,0x3F, 0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,0x3C,0x3D,0xFF,0xFF,0xFF,0x00,0xFF,0xFF, 0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E, 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF, 0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28, 0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,0x31,0x32,0x33,0xFF,0xFF,0xFF,0xFF,0xFF }; /// <summary> /// 将 Base64 编码字符串解码为字节数组 /// </summary> /// <param name="base64String">用于解码的 Base64 编码字符串</param> /// <returns>解码后的字节数组</returns> /// <remarks> /// 注意: /// 1.字符串中允许任意的空白字符、回车换行符、连字符 /// 2.微软的Convert.FromBase64String不能处理连字符 /// </remarks> public static Byte[] DecodeBase64(String base64String) { if (String.IsNullOrEmpty(base64String)) return null; Int32 Length = base64String.Length; using (MemoryStream memStream = new MemoryStream(((Length + 3) >> 2) * 3)) { Int32 Index = 0; Byte Previous = 0; for (Int32 i = 0; i < Length; i++) { Int32 CharValue = base64String[i]; if (CharValue >= 0x80) throw new ArgumentException(); // 错误字符 Byte OrderValue = DATA_ASCII2BIN[CharValue]; if (OrderValue == 0xFF) throw new ArgumentException(); // 错误字符 // 跳过空白字符、回车换行字符、连字符 if ((OrderValue | 0x13) == B64_NOT_BASE64) continue; if (Index == 0) { if (CharValue == '=') throw new ArgumentException(); Previous = OrderValue; Index++; } else if (Index == 1) { if (CharValue == '=') throw new ArgumentException(); memStream.WriteByte((Byte)((Previous << 2) | (OrderValue >> 4))); Previous = OrderValue; Index++; } else if (Index == 2) { if (CharValue == '=') { // 简化处理,不再判断第二个'=' Index = 0; break; } memStream.WriteByte((Byte)((Previous << 4) | (OrderValue >> 2))); Previous = OrderValue; Index++; } else { Index = 0; if (CharValue == '=') break; memStream.WriteByte((Byte)((Previous << 6) | OrderValue)); } } // End for // 有效字符个数必须是4的倍数 if (Index == 0) return memStream.ToArray(); else throw new ArgumentException(); } } } }