using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ProjectBase.Data.Encrypt { /// /// 基于Base64的加密编码辅助类, /// 可以设置不同的密码表来获取不同的编码与解码 /// public class Base64Util { /// /// 构造函数,初始化编码表 /// public Base64Util() { this.InitDict(); } protected static Base64Util s_b64 = new Base64Util(); /// /// 使用默认的密码表加密字符串 /// /// 待加密字符串 /// public static string Encrypt(string input) { return s_b64.Encode(input); } /// /// 使用默认的密码表解密字符串 /// /// 待解密字符串 /// public static string Decrypt(string input) { return s_b64.Decode(input); } /// /// 获取具有标准的Base64密码表的加密类 /// /// public static Base64Util GetStandardBase64() { Base64Util b64 = new Base64Util(); b64.Pad = "="; b64.CodeTable = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; return b64; } protected string m_codeTable = @"ABCDEFGHIJKLMNOPQRSTUVWXYZbacdefghijklmnopqrstu_wxyz0123456789*-"; protected string m_pad = "v"; protected Dictionary m_t1 = new Dictionary(); protected Dictionary m_t2 = new Dictionary(); /// /// 密码表 /// public string CodeTable { get { return m_codeTable; } set { if (value == null) { throw new Exception("密码表不能为null"); } else if (value.Length < 64) { throw new Exception("密码表长度必须至少为64"); } else { this.ValidateRepeat(value); this.ValidateEqualPad(value, m_pad); m_codeTable = value; this.InitDict(); } } } /// /// 补码 /// public string Pad { get { return m_pad; } set { if (value == null) { throw new Exception("密码表的补码不能为null"); } else if (value.Length != 1) { throw new Exception("密码表的补码长度必须为1"); } else { this.ValidateEqualPad(m_codeTable, value); m_pad = value; this.InitDict(); } } } /// /// 返回编码后的字符串 /// /// 原字符串 /// public string Encode(string source) { if (source == null || source == "") { return ""; } else { StringBuilder sb = new StringBuilder(); byte[] tmp = System.Text.UTF8Encoding.UTF8.GetBytes(source); int remain = tmp.Length % 3; int patch = 3 - remain; if (remain != 0) { Array.Resize(ref tmp, tmp.Length + patch); } int cnt = (int)Math.Ceiling(tmp.Length * 1.0 / 3); for (int i = 0; i < cnt; i++) { sb.Append(this.EncodeUnit(tmp[i * 3], tmp[i * 3 + 1], tmp[i * 3 + 2])); } if (remain != 0) { sb.Remove(sb.Length - patch, patch); for (int i = 0; i < patch; i++) { sb.Append(m_pad); } } return sb.ToString(); } } protected string EncodeUnit(params byte[] unit) { int[] obj = new int[4]; obj[0] = (unit[0] & 0xfc) >> 2; obj[1] = ((unit[0] & 0x03) << 4) + ((unit[1] & 0xf0) >> 4); obj[2] = ((unit[1] & 0x0f) << 2) + ((unit[2] & 0xc0) >> 6); obj[3] = unit[2] & 0x3f; StringBuilder sb = new StringBuilder(); for (int i = 0; i < obj.Length; i++) { sb.Append(this.GetEC((int)obj[i])); } return sb.ToString(); } protected char GetEC(int code) { return m_t1[code];//m_codeTable[code]; } /// /// 获得解码字符串 /// /// 原字符串 /// public string Decode(string source) { if (source == null || source == "") { return ""; } else { List list = new List(); char[] tmp = source.ToCharArray(); int remain = tmp.Length % 4; if (remain != 0) { Array.Resize(ref tmp, tmp.Length - remain); } int patch = source.IndexOf(m_pad); if (patch != -1) { patch = source.Length - patch; } int cnt = tmp.Length / 4; for (int i = 0; i < cnt; i++) { this.DecodeUnit(list, tmp[i * 4], tmp[i * 4 + 1], tmp[i * 4 + 2], tmp[i * 4 + 3]); } for (int i = 0; i < patch; i++) { list.RemoveAt(list.Count - 1); } return System.Text.Encoding.UTF8.GetString(list.ToArray()); } } protected void DecodeUnit(List byteArr, params char[] chArray) { int[] res = new int[3]; byte[] unit = new byte[chArray.Length]; for (int i = 0; i < chArray.Length; i++) { unit[i] = this.FindChar(chArray[i]); } res[0] = (unit[0] << 2) + ((unit[1] & 0x30) >> 4); res[1] = ((unit[1] & 0xf) << 4) + ((unit[2] & 0x3c) >> 2); res[2] = ((unit[2] & 0x3) << 6) + unit[3]; for (int i = 0; i < res.Length; i++) { byteArr.Add((byte)res[i]); } } protected byte FindChar(char ch) { int pos = m_t2[ch];//m_codeTable.IndexOf(ch); return (byte)pos; } /// /// 初始化双向哈希字典 /// protected void InitDict() { m_t1.Clear(); m_t2.Clear(); m_t2.Add(m_pad[0], -1); for (int i = 0; i < m_codeTable.Length; i++) { m_t1.Add(i, m_codeTable[i]); m_t2.Add(m_codeTable[i], i); } } /// /// 检查字符串中的字符是否有重复 /// /// 待检查字符串 /// protected void ValidateRepeat(string input) { for (int i = 0; i < input.Length; i++) { if (input.LastIndexOf(input[i]) > i) { throw new Exception("密码表中含有重复字符:" + input[i]); } } } /// /// 检查字符串是否包含补码字符 /// /// 待检查字符串 /// protected void ValidateEqualPad(string input, string pad) { if (input.IndexOf(pad) > -1) { throw new Exception("密码表中包含了补码字符:" + pad); } } /// /// 测试 /// protected void Test() { //m_codeTable = @"STUVWXYZbacdefghivklABCDEFGHIJKLMNOPQRmnopqrstu!wxyz0123456789+/"; //m_pad = "j"; this.InitDict(); string test = "abc ABC 你好!◎#¥%……!@#$%^"; string encode = this.Encode("false"); string decode = this.Decode(encode); Console.WriteLine(encode); Console.WriteLine(test == decode); } } }