1. 程式人生 > >QQ的TEA填充演算法C#實現 By Red_angelX

QQ的TEA填充演算法C#實現 By Red_angelX

{    
        
//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 +44);
            
long a = getUnsignedInt(arrayKey, 04);
            
long b = getUnsignedInt(arrayKey, 44);
            
long c = getUnsignedInt(arrayKey, 84);
            
long d = getUnsignedInt(arrayKey, 124);
            
for(int i=1;i<=16;i++)
            
{