Newer
Older
SensorHub-NoiseCorr / SensorHub.Servers / TEA.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace SensorHub.Servers
{
    public static class TEA
    {
        private static Byte[] TEA_key = new Byte[16] { 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 97, 98, 99, 100, 101, 102 };
        static void tea_encrypt(ref UInt32 v1, ref UInt32 v2, UInt32 a, UInt32 b, UInt32 c, UInt32 d)
        {
            UInt32 y = v1, z = v2, sum = 0, i;
            UInt32 delta = 0x9e3779b9;
            //UInt32 a = k1, b = k2, c = k3, d = k4;  

            for (i = 0; i < 32; i++)
            {
                sum += delta;
                y += ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
                z += ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
            }
            v1 = y;
            v2 = z;
        }

        /*********************************************************************
        *							tea解密
        *参数:v:要解密的数据,长度为8字节
        *     k:解密用的key,长度为16字节
        **********************************************************************/

        static void tea_decrypt(ref UInt32 v1, ref UInt32 v2, UInt32 a, UInt32 b, UInt32 c, UInt32 d)
        {
            UInt32 y = v1, z = v2, sum = 0xC6EF3720, i;
            UInt32 delta = 0x9e3779b9;
            //UInt32 a = k[0], b = k[1], c = k[2], d = k[3];    

            for (i = 0; i < 32; i++)
            {
                z -= ((y << 4) + c) ^ (y + sum) ^ ((y >> 5) + d);
                y -= ((z << 4) + a) ^ (z + sum) ^ ((z >> 5) + b);
                sum -= delta;
            }
            v1 = y;
            v2 = z;
        }

        /*********************************************************************
        *							加密算法
        *参数:src:源数据,所占空间必须为8字节的倍数.加密完成后密文也存放在这
        *     size_src:源数据大小,单位字节
        *     key:密钥,16字节
        *返回:密文的字节数
        **********************************************************************/

        public static int encrypt(ref Byte[] src, int size_src)
        {
            UInt16 a = 0;
            UInt16 i = 0;
            int num = 0;

            //将明文补足为8字节的倍数
            a = (UInt16)(size_src % 8);
            if (a != 0)
            {
                for (i = 0; i < 8 - a; i++)
                {
                    src[size_src++] = 0;
                }
            }

            UInt32 Key1 = (UInt32)(TEA_key[3] << 24 | TEA_key[2] << 16 | TEA_key[1] << 8 | TEA_key[0]);
            UInt32 Key2 = (UInt32)(TEA_key[7] << 24 | TEA_key[6] << 16 | TEA_key[5] << 8 | TEA_key[4]);
            UInt32 Key3 = (UInt32)(TEA_key[11] << 24 | TEA_key[10] << 16 | TEA_key[9] << 8 | TEA_key[8]);
            UInt32 Key4 = (UInt32)(TEA_key[15] << 24 | TEA_key[14] << 16 | TEA_key[13] << 8 | TEA_key[12]);

            //加密
            num = (UInt16)(size_src / 8);
            for (i = 0; i < num; i++)
            {
                //tea_encrypt((UInt32*)(src + i * 8), key);
                UInt32 src1 = (UInt32)(src[i * 8 + 3] << 24 | src[i * 8 + 2] << 16 | src[i * 8 + 1] << 8 | src[i * 8 + 0]);
                UInt32 src2 = (UInt32)(src[i * 8 + 7] << 24 | src[i * 8 + 6] << 16 | src[i * 8 + 5] << 8 | src[i * 8 + 4]);

                tea_encrypt(ref src1, ref src2, Key1, Key2, Key3, Key4);

                src[i * 8 + 3] = (Byte)(src1 >> 24);
                src[i * 8 + 2] = (Byte)(src1 >> 16);
                src[i * 8 + 1] = (Byte)(src1 >> 8);
                src[i * 8 + 0] = (Byte)(src1);
                src[i * 8 + 7] = (Byte)(src2 >> 24);
                src[i * 8 + 6] = (Byte)(src2 >> 16);
                src[i * 8 + 5] = (Byte)(src2 >> 8);
                src[i * 8 + 4] = (Byte)(src2);

            }
            return size_src;
        }

        /*********************************************************************
        *							解密算法
        *参数:src:源数据,所占空间必须为8字节的倍数.解密完成后明文也存放在这
        *     size_src:源数据大小,单位字节
        *     key:密钥,16字节
        *返回:明文的字节数,如果失败,返回0
        **********************************************************************/

        public static int decrypt(ref Byte[] src, int size_src)
        {
            UInt16 i = 0;
            UInt16 num = 0;

            //判断长度是否为8的倍数
            if (size_src % 8 != 0)
            {
                //printf("\r\nchang du bu shi 8!!");
                return 0;
            }

            UInt32 Key1 = (UInt32)(TEA_key[3] << 24 | TEA_key[2] << 16 | TEA_key[1] << 8 | TEA_key[0]);
            UInt32 Key2 = (UInt32)(TEA_key[7] << 24 | TEA_key[6] << 16 | TEA_key[5] << 8 | TEA_key[4]);
            UInt32 Key3 = (UInt32)(TEA_key[11] << 24 | TEA_key[10] << 16 | TEA_key[9] << 8 | TEA_key[8]);
            UInt32 Key4 = (UInt32)(TEA_key[15] << 24 | TEA_key[14] << 16 | TEA_key[13] << 8 | TEA_key[12]);

            //解密
            num = (Byte)(size_src / 8);
            for (i = 0; i < num; i++)
            {
                //tea_decrypt((UInt32*)(src + i * 8), (UInt32*)key);

                UInt32 src1 = (UInt32)(src[i * 8 + 3] << 24 | src[i * 8 + 2] << 16 | src[i * 8 + 1] << 8 | src[i * 8 + 0]);
                UInt32 src2 = (UInt32)(src[i * 8 + 7] << 24 | src[i * 8 + 6] << 16 | src[i * 8 + 5] << 8 | src[i * 8 + 4]);

                tea_decrypt(ref src1, ref src2, Key1, Key2, Key3, Key4);

                src[i * 8 + 3] = (Byte)(src1 >> 24);
                src[i * 8 + 2] = (Byte)(src1 >> 16);
                src[i * 8 + 1] = (Byte)(src1 >> 8);
                src[i * 8 + 0] = (Byte)(src1);
                src[i * 8 + 7] = (Byte)(src2 >> 24);
                src[i * 8 + 6] = (Byte)(src2 >> 16);
                src[i * 8 + 5] = (Byte)(src2 >> 8);
                src[i * 8 + 4] = (Byte)(src2);
            }

            return size_src;
        }
    }
}