QQ的TEA填充演算法C#實現 By Red_angelX
阿新 • • 發佈:2019-01-23
{
//QQ TEA-16 Encrypt/Decrypt Class
//
//
//And also LumaQQ//s source code
// CopyRight:No CopyRight^_^
// Author : Red_angelX
// NetWork is Free,Tencent is ****!
//
//Class Begin
//AD:Find Job!!,If you Want Give me a Job,Content Me!!
//Copied & translated from LumaQQ//s source code `From LumaQQ///s source code:
privatebyte[] Plain; //指向當前的明文塊
privatebyte[] prePlain ; //指向前面一個明文塊
privatebyte[] Out; //輸出的密文或者明文
privatelong Crypt, preCrypt; //當前加密的密文位置和上一次加密的密文塊位置,他們相差8
privatelong Pos; //當前處理的加密解密塊的位置
privatelong padding; //填充數
privatebyte[] Key =newbyte[16]; //金鑰
privatebool Header; //用於加密時,表示當前是否是第一個8位元組塊,因為加密演算法
//是反饋的,但是最開始的8個位元組沒有反饋可用,所有需要標
//明這種情況
privatelong contextStart; //這個表示當前解密開始的位置,之所以要這麼一個變數是為了
//避免當解密到最後時後面已經沒有資料,這時候就會出錯,這
//個變數就是用來判斷這種情況免得出錯
public QQCrypt()
...{
//
// TODO: 在此處新增建構函式邏輯
//
}
//Push 資料
byte[] CopyMemory(byte[] arr,int arr_index,long input) //lenth = 4
...{
if(arr_index+4> arr.Length)
...{
// 不能執行
return arr;
}
arr[arr_index+3]=(byte)((input &0xff000000) >>24);
arr[arr_index+2]=(byte)((input &0x00ff0000) >>16);
arr[arr_index+1]=(byte)((input &0x0000ff00) >>8);
arr[arr_index]=(byte)(input &0x000000ff);
arr[arr_index] &=0xff;
arr[arr_index+1] &=0xff;
arr[arr_index+2] &=0xff;
arr[arr_index+3] &=0xff;
return arr;
}
long CopyMemory(long Out,byte[] arr,int arr_index)
...{
if(arr_index+4> arr.Length)
...{
return Out;
//不能執行
}
long x1 = arr[arr_index+3] <<24;
long x2 = arr[arr_index+2] <<16;
long x3 = arr[arr_index+1] <<8;
long x4 = arr[arr_index];
long o = x1 | x2 | x3 | x4;
o &=0xffffffff;
return o;
}
long getUnsignedInt(byte[] arrayIn, int offset,int len /**//*Default is 4*/)
...{
long ret =0;
int end =0;
if (len >8)
end = offset +8;
else
end = offset + len;
for (int i = offset; i < end; i++)
...{
ret <<=8;
ret |= arrayIn[i] &0xff;
}
return (ret &0xffffffff) | (ret >>32);
}
long Rand()
...{
Random rd =new Random();
long ret;
ret = rd.Next() + (rd.Next() %1024);
return ret;
}
privatebyte[] Decipher(byte[] arrayIn,byte[] arrayKey,long offset)
...{
//long Y,z,a,b,c,d;
long sum,delta;
//Y=z=a=b=c=d=0;
byte[] tmpArray =newbyte[24];
byte[] tmpOut =newbyte[8];
if(arrayIn.Length <8)
...{
// Error:return
return tmpOut;
}
if(arrayKey.Length <16)
...{
// Error:return
return tmpOut;
}
sum =0xE3779B90;
sum = sum &0xFFFFFFFF;
delta =0x9E3779B9;
delta = delta &0xFFFFFFFF;
/**//*tmpArray[3] = arrayIn[offset];
tmpArray[2] = arrayIn[offset + 1];
tmpArray[1] = arrayIn[offset + 2];
tmpArray[0] = arrayIn[offset + 3];
tmpArray[7] = arrayIn[offset + 4];
tmpArray[6] = arrayIn[offset + 5];
tmpArray[5] = arrayIn[offset + 6];
tmpArray[4] = arrayIn[offset + 7];
tmpArray[11] = arrayKey[0];
tmpArray[10] = arrayKey[1];
tmpArray[9] = arrayKey[2];
tmpArray[8] = arrayKey[3];
tmpArray[15] = arrayKey[4];
tmpArray[14] = arrayKey[5];
tmpArray[13] = arrayKey[6];
tmpArray[12] = arrayKey[7];
tmpArray[19] = arrayKey[8];
tmpArray[18] = arrayKey[9];
tmpArray[17] = arrayKey[10];
tmpArray[16] = arrayKey[11];
tmpArray[23] = arrayKey[12];
tmpArray[22] = arrayKey[13];
tmpArray[21] = arrayKey[14];
tmpArray[20] = arrayKey[15];
Y=CopyMemory(Y,tmpArray,0);
z=CopyMemory(z,tmpArray,4);
a=CopyMemory(a,tmpArray,8);
b=CopyMemory(b,tmpArray,12);
c=CopyMemory(c,tmpArray,16);
d=CopyMemory(d,tmpArray,20);*/
long Y = getUnsignedInt(arrayIn, (int)offset, 4);
long z = getUnsignedInt(arrayIn, (int)offset +4, 4);
long a = getUnsignedInt(arrayKey, 0, 4);
long b = getUnsignedInt(arrayKey, 4, 4);
long c = getUnsignedInt(arrayKey, 8, 4);
long d = getUnsignedInt(arrayKey, 12, 4);
for(int i=1;i<=16;i++)
...{
//QQ TEA-16 Encrypt/Decrypt Class
//
//
//And also LumaQQ//s source code
// CopyRight:No CopyRight^_^
// Author : Red_angelX
// NetWork is Free,Tencent is ****!
//
//Class Begin
//AD:Find Job!!,If you Want Give me a Job,Content Me!!
//Copied & translated from LumaQQ//s source code `From LumaQQ///s source code:
privatebyte[] Plain; //指向當前的明文塊
privatebyte[] prePlain ; //指向前面一個明文塊
privatebyte[] Out; //輸出的密文或者明文
privatelong Crypt, preCrypt;
privatelong Pos; //當前處理的加密解密塊的位置
privatelong padding; //填充數
privatebyte[] Key =newbyte[16]; //金鑰
privatebool Header; //用於加密時,表示當前是否是第一個8位元組塊,因為加密演算法
//明這種情況
privatelong contextStart; //這個表示當前解密開始的位置,之所以要這麼一個變數是為了
//避免當解密到最後時後面已經沒有資料,這時候就會出錯,這
//個變數就是用來判斷這種情況免得出錯
public QQCrypt()
...{
//
// TODO: 在此處新增建構函式邏輯
//
}
//Push 資料
byte[] CopyMemory(byte[] arr,int arr_index,long input) //lenth = 4
...{
if(arr_index+4> arr.Length)
...{
// 不能執行
return arr;
}
arr[arr_index+3]=(byte)((input &0xff000000) >>24);
arr[arr_index+2]=(byte)((input &0x00ff0000) >>16);
arr[arr_index+1]=(byte)((input &0x0000ff00) >>8);
arr[arr_index]=(byte)(input &0x000000ff);
arr[arr_index] &=0xff;
arr[arr_index+1] &=0xff;
arr[arr_index+2] &=0xff;
arr[arr_index+3] &=0xff;
return arr;
}
long CopyMemory(long Out,byte[] arr,int arr_index)
...{
if(arr_index+4> arr.Length)
...{
return Out;
//不能執行
}
long x1 = arr[arr_index+3] <<24;
long x2 = arr[arr_index+2] <<16;
long x3 = arr[arr_index+1] <<8;
long x4 = arr[arr_index];
long o = x1 | x2 | x3 | x4;
o &=0xffffffff;
return o;
}
long getUnsignedInt(byte[] arrayIn, int offset,int len /**//*Default is 4*/)
...{
long ret =0;
int end =0;
if (len >8)
end = offset +8;
else
end = offset + len;
for (int i = offset; i < end; i++)
...{
ret <<=8;
ret |= arrayIn[i] &0xff;
}
return (ret &0xffffffff) | (ret >>32);
}
long Rand()
...{
Random rd =new Random();
long ret;
ret = rd.Next() + (rd.Next() %1024);
return ret;
}
privatebyte[] Decipher(byte[] arrayIn,byte[] arrayKey,long offset)
...{
//long Y,z,a,b,c,d;
long sum,delta;
//Y=z=a=b=c=d=0;
byte[] tmpArray =newbyte[24];
byte[] tmpOut =newbyte[8];
if(arrayIn.Length <8)
...{
// Error:return
return tmpOut;
}
if(arrayKey.Length <16)
...{
// Error:return
return tmpOut;
}
sum =0xE3779B90;
sum = sum &0xFFFFFFFF;
delta =0x9E3779B9;
delta = delta &0xFFFFFFFF;
/**//*tmpArray[3] = arrayIn[offset];
tmpArray[2] = arrayIn[offset + 1];
tmpArray[1] = arrayIn[offset + 2];
tmpArray[0] = arrayIn[offset + 3];
tmpArray[7] = arrayIn[offset + 4];
tmpArray[6] = arrayIn[offset + 5];
tmpArray[5] = arrayIn[offset + 6];
tmpArray[4] = arrayIn[offset + 7];
tmpArray[11] = arrayKey[0];
tmpArray[10] = arrayKey[1];
tmpArray[9] = arrayKey[2];
tmpArray[8] = arrayKey[3];
tmpArray[15] = arrayKey[4];
tmpArray[14] = arrayKey[5];
tmpArray[13] = arrayKey[6];
tmpArray[12] = arrayKey[7];
tmpArray[19] = arrayKey[8];
tmpArray[18] = arrayKey[9];
tmpArray[17] = arrayKey[10];
tmpArray[16] = arrayKey[11];
tmpArray[23] = arrayKey[12];
tmpArray[22] = arrayKey[13];
tmpArray[21] = arrayKey[14];
tmpArray[20] = arrayKey[15];
Y=CopyMemory(Y,tmpArray,0);
z=CopyMemory(z,tmpArray,4);
a=CopyMemory(a,tmpArray,8);
b=CopyMemory(b,tmpArray,12);
c=CopyMemory(c,tmpArray,16);
d=CopyMemory(d,tmpArray,20);*/
long Y = getUnsignedInt(arrayIn, (int)offset, 4);
long z = getUnsignedInt(arrayIn, (int)offset +4, 4);
long a = getUnsignedInt(arrayKey, 0, 4);
long b = getUnsignedInt(arrayKey, 4, 4);
long c = getUnsignedInt(arrayKey, 8, 4);
long d = getUnsignedInt(arrayKey, 12, 4);
for(int i=1;i<=16;i++)
...{