对整数加密。。。

因为之前的数据库的所有 id 字段都是使用的整数,现在需要对外暴露接口,所以需要对整数进行加密,变成类似于 guid 的形式。。
目的类似于 GUID, 对于相同类型相同ID的记录,总会产生相同的 guid,
例如: 
"Id":"d34032f7bde406bfb8ef7447d898d0a2",  
"PartnerId":"b8feb9b3db27f6d0d3204774b353d6e2"
估计看到的人都以为是 Guid , 也不会想着去解密了。。

        /// <summary>
        /// 随机的数,但是一旦确定,不能够改变;
        /// </summary>
        public static int[] Random = new int[]
        {
            123458817, 123459781, 345978112, 597811234, 781123459, 112345978, 477, 287,
            1233645, 5415321, 11100, 7, 5423, 8172, 477, 21837,
            1232145, 2541321, 1020, 8987, 5443, 887, 47927, 22867,
            12312345, 5423211, 1040, 897, 54, 8782, 44747, 218,
        };
        /// <summary>
        /// 
        /// </summary>
        public static char[] GuidArray = new char[]
        {
            '0', 'a', 'b','e','f','c','d','2','4','1','3','5','7','6','8','9'
        };

        /// <summary>
        /// 根据类型和名称,相同的类型和 id 将产生相同的 guid, 
        /// </summary>
        /// <param name="id"></param>
        /// <param name="typeName"></param>
        /// <returns></returns>
        private static string ProductGuid(int id, string typeName)
        {
            char[] ran = new char[32];
            var xId = Math.Abs(id ^ typeName.GetHashCode());
            Random.ForEach((item, index) =>
            {
                var xx = Math.Abs(xId ^ item) % 16;
                ran[index] = GuidArray[xx];
            });
            return new string(ran);
        }

        /// <summary>
        /// 将Id藏起来到Guid中;返回加密后的字符串;
        /// 对于相同类型的Id,会产生同样的 Guid;
        /// 但是对于不同类型的相同Id,可能会产生不同的Guid;
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="debug"></param>
        /// <returns></returns>
        public static string CryptIdInGuid<T>(int? _id, bool debug = false)
        {
            if (!_id.HasValue || _id < 0) return null;
            return CryptIdInGuid(_id, typeof(T), debug);
        }

        /// <summary>
        /// 将Id藏起来到Guid中;返回加密后的字符串;
        /// 如果 id 小于等于0,返回空;
        /// 对于相同类型的相同Id,会产生同样的 Guid;
        /// 对于相同类型的不同Id,会产生不同的 Guid;
        /// 但是对于不同类型的不同Id,可能会产生相同的Guid;
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="type"></param>
        /// <param name="debug"></param>
        /// <returns></returns>
        public static string CryptIdInGuid(int? _id, Type type, bool debug=false)
        {
            if (!_id.HasValue || _id < 0) return null;
            var entityTypeName = ObjectContext.GetObjectType(type).Name;
            return CryptIdInGuid(_id, entityTypeName, debug);
        }

        /// <summary>
        /// 将Id藏起来到Guid中;返回加密后的字符串;
        /// 如果 id 小于等于0,返回空;
        /// 对于相同类型的相同Id,会产生同样的 Guid;
        /// 但是对于不同类型的相同Id,可能会产生不同的Guid;
        /// </summary>
        /// <param name="_id"></param>
        /// <param name="typeName"></param>
        /// <param name="debug"></param>
        /// <returns></returns>
        private static string CryptIdInGuid(int? _id, string typeName, bool debug = false)
        {
            if (!_id.HasValue || _id < 0) return null;
            var id = _id.Value;
            string val = null;
            var typeHash = Math.Abs(typeName.GetHashCode());  // 不要使用 Type,使用类型名称, 因为 Type的HashCode将根据内部值的不同而有所不同;  
            var guid = ProductGuid(id, typeName);
            var longId = (id * 135721L);
            var idVal = longId.ToString("x").ToLower().ToCharArray(); //id 转换成为16进制的字符数组;
            //if (idVal.Length > 11) throw new Exception("数字溢出"); 
            var bytes = guid.ToCharArray();
            int beginPos = (id & typeHash) % 16; // new Random().Next(16);
            bytes[bytes.Length - 1] = beginPos.ToString("x").ToCharArray()[0]; //倒数第1位用来表示起始位置;
            var len = idVal.Length.ToString("x").ToCharArray()[0];
            bytes[beginPos + 11] = len; //倒数第2位用来表示长度位置; 理论上不可能超过 16位长度
            var crcString = ((id ^ 123456789) % (256 * 16)).ToString("x");
            var crc = crcString.ToCharArray();   //校验字符数组位,3位长度;
            if (crc.Length == 1)
            {
                crc = new char[] { '0', '0', crc[0] };
            }
            if (crc.Length == 2)
            {
                crc = new char[] { '0', crc[0], crc[1] };
            }
            Array.Copy(crc, 0, bytes, 28, crc.Length);

            idVal.ForEach((chr, pos) =>
            {
                bytes[beginPos + pos] = chr;
            });
            val = new string(bytes);
            if (debug)
            {
                LogUtil.xLogUtil.Warn(
"加密过程:{1}{2}type:{3}{2}typeHash:{4}{2}beginPos:{5}{2}len:{6}{2}sub:{7}{2}subLong:{8}{2}crc:{9}{2}id:{0}",
null,
id, val, Environment.NewLine, typeName, typeHash, beginPos, len, idVal, longId, crcString);
            }
            return val;
        }

加解密效率约 1秒1000000次。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值