开启辅助访问 切换到宽版

精易论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

用微信号发送消息登录论坛

新人指南 邀请好友注册 - 我关注人的新帖 教你赚取精币 - 每日签到


求职/招聘- 论坛接单- 开发者大厅

论坛版规 总版规 - 建议/投诉 - 应聘版主 - 精华帖总集 积分说明 - 禁言标准 - 有奖举报

查看: 7385|回复: 2
收起左侧

[C#源码] TEA加密解密工具类

[复制链接]
发表于 2018-7-21 15:39:42 | 显示全部楼层 |阅读模式   广东省珠海市
/// <summary>
    /// TEA加密解密工具类
    /// </summary>
    internal class TEAUtil
    {
        /// <summary>
        /// 加密解密消息包的工具类.
        /// </summary>
        private static void code(byte[] In, int inOffset, int inPos, byte[] Out, int outOffset, int outPos, byte[] key)
        {
            if (outPos > 0)
            {
                for (int i = 0; i < 8; i++)
                {
                    In[outOffset + outPos + i] = (byte)(In[inOffset + inPos + i] ^ Out[outOffset + outPos + i - 8]);
                }
            }
            uint[] formattedKey = FormatKey(key);
            uint y = ConvertByteArrayToUInt(In, outOffset + outPos);
            uint z = ConvertByteArrayToUInt(In, outOffset + outPos + 4);
            uint sum = 0;
            uint delta = 0x9e3779b9;
            uint n = 16;
            while (n-- > 0)
            {
                sum += delta;
                y += ((z << 4) + formattedKey[0]) ^ (z + sum) ^ ((z >> 5) + formattedKey[1]);
                z += ((y << 4) + formattedKey[2]) ^ (y + sum) ^ ((y >> 5) + formattedKey[3]);
            }
            Array.Copy(ConvertUIntToByteArray(y), 0, Out, outOffset + outPos, 4);
            Array.Copy(ConvertUIntToByteArray(z), 0, Out, outOffset + outPos + 4, 4);
            if (inPos > 0)
            {
                for (int i = 0; i < 8; i++)
                {
                    Out[outOffset + outPos + i] = (byte)(Out[outOffset + outPos + i] ^ In[inOffset + inPos + i - 8]);
                }
            }
        }
        private static void decode(byte[] In, int inOffset, int inPos, byte[] Out, int outOffset, int outPos, byte[] key)
        {
            if (outPos > 0)
            {
                for (int i = 0; i < 8; i++)
                {
                    Out[outOffset + outPos + i] = (byte)(In[inOffset + inPos + i] ^ Out[outOffset + outPos + i - 8]);
                }
            }
            else
            {
                Array.Copy(In, inOffset, Out, outOffset, 8);
            }
            uint[] formattedKey = FormatKey(key);
            uint y = ConvertByteArrayToUInt(Out, outOffset + outPos);
            uint z = ConvertByteArrayToUInt(Out, outOffset + outPos + 4);
            uint sum = 0xE3779B90;
            uint delta = 0x9e3779b9;
            uint n = 16;
            while (n-- > 0)
            {
                z -= ((y << 4) + formattedKey[2]) ^ (y + sum) ^ ((y >> 5) + formattedKey[3]);
                y -= ((z << 4) + formattedKey[0]) ^ (z + sum) ^ ((z >> 5) + formattedKey[1]);
                sum -= delta;
            }
            Array.Copy(ConvertUIntToByteArray(y), 0, Out, outOffset + outPos, 4);
            Array.Copy(ConvertUIntToByteArray(z), 0, Out, outOffset + outPos + 4, 4);
        }
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="input">需要被解密的密文</param>
        /// <param name="key">密钥</param>
        /// <returns>Message 已解密的消息</returns>
        public static byte[] Decrypt(byte[] input, byte[] key)
        {
            return Decrypt(input, 0, input.Length, key);
        }
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="input">需要加密的明文</param>
        /// <param name="key">密钥</param>
        /// <returns>Message 密文</returns>
        public static byte[] Encrypt(byte[] input, byte[] key)
        {
            return Encrypt(input, 0, input.Length, key);
        }
        /// <summary>
        /// 解密
        /// </summary>
        /// <param name="In">密文</param>
        /// <param name="offset">密文开始的位置</param>
        /// <param name="len">密文长度</param>
        /// <param name="key">密钥</param>
        /// <returns>返回明文</returns>
        public static byte[] Decrypt(byte[] In, int offset, int len, byte[] key)
        {
            // 因为QQ消息加密之后至少是16字节,并且肯定是8的倍数,这里检查这种情况
            if ((len % 8 != 0) || (len < 16))
            {
                return null;
            }
            byte[] Out = new byte[len];
            for (int i = 0; i < len; i += 8)
            {
                decode(In, offset, i, Out, 0, i, key);
            }
            for (int i = 8; i < len; i++)
            {
                Out[i] = (byte)(Out[i] ^ In[offset + i - 8]);
            }
            int pos = Out[0] & 0x07;
            len = len - pos - 10;
            byte[] res = new byte[len];
            Array.Copy(Out, pos + 3, res, 0, len);
            return res;
        }
        /// <summary>
        /// 加密
        /// </summary>
        /// <param name="In">明文</param>
        /// <param name="offset">明文开始的位置</param>
        /// <param name="len">明文长度</param>
        /// <param name="key">密钥</param>
        /// <returns>返回密文</returns>
        public static byte[] Encrypt(byte[] In, int offset, int len, byte[] key)
        {
            Random rand = new Random();
            // 计算头部填充字节数
            int pos = (len + 10) % 8;
            if (pos != 0)
            {
                pos = 8 - pos;
            }
            byte[] plain = new byte[len + pos + 10];
            plain[0] = (byte)((rand.Next() & 0xF8) | pos);
            for (int i = 1; i < pos + 3; i++)
            {
                plain[i] = (byte)(rand.Next() & 0xFF);
            }
            Array.Copy(In, 0, plain, pos + 3, len);
            for (int i = pos + 3 + len; i < plain.Length; i++)
            {
                plain[i] = 0x0;
            }
            // 定义输出流
            byte[] outer = new byte[len + pos + 10];
            for (int i = 0; i < outer.Length; i += 8)
            {
                code(plain, 0, i, outer, 0, i, key);
            }
            return outer;
        }
        //格式化密钥
        private static uint[] FormatKey(byte[] key)
        {
            if (key.Length == 0)
            {
                throw new ArgumentException("Key must be between 1 and 16 characters in length");
            }
            byte[] refineKey = new byte[16];
            if (key.Length < 16)
            {
                Array.Copy(key, 0, refineKey, 0, key.Length);
                for (int k = key.Length; k < 16; k++)
                {
                    refineKey[k] = 0x20;
                }
            }
            else
            {
                Array.Copy(key, 0, refineKey, 0, 16);
            }
            uint[] formattedKey = new uint[4];
            int j = 0;
            for (int i = 0; i < refineKey.Length; i += 4)
            {
                formattedKey[j++] = ConvertByteArrayToUInt(refineKey, i);
            }
            return formattedKey;
        }
        private static byte[] ConvertUIntToByteArray(uint v)
        {
            byte[] result = new byte[4];
            result[0] = (byte)((v >> 24) & 0xFF);
            result[1] = (byte)((v >> 16) & 0xFF);
            result[2] = (byte)((v >> 8) & 0xFF);
            result[3] = (byte)((v >> 0) & 0xFF);
            return result;
        }
        private static uint ConvertByteArrayToUInt(byte[] v, int offset)
        {
            if (offset + 4 > v.Length)
            {
                return 0;
            }
            uint output;
            output = (uint)(v[offset] << 24);
            output |= (uint)(v[offset + 1] << 16);
            output |= (uint)(v[offset + 2] << 8);
            output |= (uint)(v[offset + 3] << 0);
            return output;
        }
    }
结帖率:67% (4/6)
发表于 2018-7-22 10:07:08 | 显示全部楼层   浙江省温州市
已将很不错了
回复 支持 反对

使用道具 举报

结帖率:100% (8/8)

签到天数: 6 天

发表于 2018-7-21 15:59:04 | 显示全部楼层   福建省漳州市
贴代码还是用代码标签贴吧
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则 致发广告者

发布主题 收藏帖子 返回列表

sitemap| 易语言源码| 易语言教程| 易语言论坛| 诚聘英才| 易语言模块| 手机版| 广告投放| 精易论坛
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论,本站内容均为会员发表,并不代表精易立场!
论坛帖子内容仅用于技术交流学习和研究的目的,严禁用于非法目的,否则造成一切后果自负!如帖子内容侵害到你的权益,请联系我们!
防范网络诈骗,远离网络犯罪 违法和不良信息举报电话0663-3422125,QQ: 800073686,邮箱:800073686@b.qq.com
Powered by Discuz! X3.4 揭阳市揭东区精易科技有限公司 ( 粤ICP备12094385号-1) 粤公网安备 44522102000125 增值电信业务经营许可证 粤B2-20192173

快速回复 返回顶部 返回列表