[修改]C#版的TEA加密算法,我所发现的比较好的版本。

///
/// 下面不是我写的,我所做的就是把所调到所有的类都集成在一起.    ///
///  我前面有一篇VB.NET版的就是根据这个写的.                        ///
///   本人E-Mail:   liwqbasic[AT]gamail.com   ([AT]换成@)        ///
///   QQ: &H12C214E9 [0x12C214E9]                                 ///
///

  1  using  System;
  2  namespace  OverredQQ.QQCore
  3  {
  4       ///   <summary>
  5       ///  加密解密QQ消息的工具类. QQ消息的加密算法是一个16次的迭代过程,并且是反馈的,每一个加密单元是8字节,输出也是8字节,密钥是16字节
  6       ///  我们以prePlain表示前一个明文块,plain表示当前明文块,crypt表示当前明文块加密得到的密文块,preCrypt表示前一个密文块
  7       ///  f表示加密算法,d表示解密算法 那么从plain得到crypt的过程是: crypt = f(plain &circ; preCrypt) &circ;
  8       ///  prePlain 所以,从crypt得到plain的过程自然是 plain = d(crypt &circ; prePlain) &circ;
  9       ///  preCrypt 此外,算法有它的填充机制,其会在明文前和明文后分别填充一定的字节数,以保证明文长度是8字节的倍数
 10       ///  填充的字节数与原始明文长度有关,填充的方法是:
 11       ///  
 12       ///   <code>
 13       ///  
 14       ///  ------- 消息填充算法 ----------- 
 15       ///  a = (明文长度 + 10) mod 8
 16       ///  if(a 不等于 0) a = 8 - a;
 17       ///  b = 随机数 &amp; 0xF8 | a;              这个的作用是把a的值保存了下来
 18       ///  plain[0] = b;                       然后把b做为明文的第0个字节,这样第0个字节就保存了a的信息,这个信息在解密时就要用来找到真正明文的起始位置
 19       ///  plain[1 至 a+2] = 随机数 &amp; 0xFF;    这里用随机数填充明文的第1到第a+2个字节
 20       ///  plain[a+3 至 a+3+明文长度-1] = 明文; 从a+3字节开始才是真正的明文
 21       ///  plain[a+3+明文长度, 最后] = 0;       在最后,填充0,填充到总长度为8的整数为止。到此为止,结束了,这就是最后得到的要加密的明文内容
 22       ///  ------- 消息填充算法 ------------
 23       ///  
 24       ///   </code>
 25       ///  
 26       ///   </summary>
 27       ///   <author>
 28       ///  
 29       ///   </author>
 30       ///   <author>
 31       ///  
 32       ///   </author>
 33       ///   <author>
 34       ///  overred
 35       ///   </author>
 36 
 37       public   struct  Crypter
 38      {
 39           /// <summary>
 40           /// 指向当前的明文块
 41           /// </summary>
 42           private   byte [] plain;
 43           /// <summary>
 44           ///  这指向前面一个明文块
 45           /// </summary>
 46           private   byte [] prePlain;
 47           /// <summary>
 48           ///  输出的密文或者明文
 49           /// </summary>
 50           private   byte [] output;
 51           /// <summary>
 52           ///  当前加密的密文位置和上一次加密的密文块位置,他们相差8
 53           /// </summary>
 54           private   int  crypt, preCrypt;
 55           /// <summary>
 56           ///  当前处理的加密解密块的位置
 57           /// </summary>
 58           private   int  pos;
 59           /// <summary>
 60           ///  填充数
 61           /// </summary>
 62           private   int  padding;
 63           /// <summary>
 64           ///  密钥
 65           /// </summary>
 66           private   byte [] key;
 67           /// <summary>
 68           ///  用于加密时,表示当前是否是第一个8字节块,因为加密算法是反馈的
 69           ///      但是最开始的8个字节没有反馈可用,所有需要标明这种情况
 70           /// </summary>
 71           private   bool  header;
 72           /// <summary>
 73           ///  这个表示当前解密开始的位置,之所以要这么一个变量是为了避免当解密到最后时
 74           ///      后面已经没有数据,这时候就会出错,这个变量就是用来判断这种情况免得出错
 75           /// </summary>
 76           private   int  contextStart;
 77 
 78           ///   <summary>
 79           ///  随机类
 80           ///   </summary>
 81           private   static  System.Random random_Renamed_Field;
 82 
 83           /// <summary>
 84           ///  随机数对象
 85           /// </summary>
 86           private   static  System.Random random;
 87 
 88           /// <summary>
 89           ///  随机数对象
 90           /// </summary>
 91           public   static  System.Random xRandom
 92          {
 93               get
 94              {
 95                   if  (random_Renamed_Field  ==   null )
 96                      random_Renamed_Field  =   new  System.Random();
 97                   return  random_Renamed_Field;
 98              }
 99          }
100          
101 
102           public   static   byte [] ToBytes( uint  a,  uint  b)
103          {
104               byte [] bytes  =   new   byte [ 8 ];
105              bytes[ 0 =  ( byte )(a  >>   24 );
106              bytes[ 1 =  ( byte )(a  >>   16 );
107              bytes[ 2 =  ( byte )(a  >>   8 );
108              bytes[ 3 =  ( byte )a;
109              bytes[ 4 =  ( byte )(b  >>   24 );
110              bytes[ 5 =  ( byte )(b  >>   16 );
111              bytes[ 6 =  ( byte )(b  >>   8 );
112              bytes[ 7 =  ( byte )b;
113               return  bytes;
114          }
115 
116 
117           ///   <summary>
118           ///  把字节数组从offset开始的len个字节转换成一个unsigned int, 因为C#里面有unsigned,所以unsigned
119           ///  int使用uint表示的。如果len大于4,则认为len等于4。如果len小于4,则高位填0  <br>
120           ///  (edited by ) 改变了算法, 性能稍微好一点. 在我的机器上测试10000次, 原始算法花费18s, 这个算法花费12s.
121           ///   </summary>
122           ///   <param name="input">
123           ///  字节数组.
124           ///   </param>
125           ///   <param name="offset">
126           ///  从哪里开始转换.
127           ///   </param>
128           ///   <param name="len">
129           ///  转换长度, 如果len超过8则忽略后面的
130           ///   </param>
131           ///   <returns>
132           ///   </returns>
133           public   static   uint  GetUInt( byte [] input,  int  offset,  int  len)
134          {
135               uint  ret  =   0 ;
136               int  end  =  (len  >   4 ?  (offset  +   4 ) : (offset  +  len);
137               for  ( int  i  =  offset; i  <  end; i ++ )
138              {
139                  ret  <<=   8 ;
140                  ret  |=  input[i];
141              }
142               return  ret;
143          }
144          
145           ///   <param name="input"> 需要被解密的密文 </param>
146           ///   <param name="key"> 密钥 </param>
147           ///   <returns>  Message 已解密的消息 </returns>
148           public   static   byte [] Decrypt( byte [] input,  byte [] key)
149          {
150              Crypter crypter  =   new  Crypter();
151              crypter.header  =   true ;
152               return  crypter.Decrypt0(input, key);
153          }
154 
155           ///   <param name="input"> 需要被解密的密文 </param>
156           ///   <param name="key"> 密钥 </param>
157           ///   <returns>  Message 已解密的消息 </returns>
158           public   static   byte [] Decrypt( byte [] input,  int  offset,  int  len,  byte [] key)
159          {
160              Crypter crypter  =   new  Crypter();
161              crypter.header  =   true ;
162               return  crypter.Decrypt0(input, offset, len, key);
163          }
164 
165           ///   <param name="input"> 需要加密的明文 </param>
166           ///   <param name="key"> 密钥 </param>
167           ///   <returns>  Message 密文 </returns>
168           public   static   byte [] Encrypt( byte [] input,  byte [] key)
169          {
170              Crypter crypter  =   new  Crypter();
171              crypter.header  =   true ;
172               return  crypter.Encrypt0(input, key);
173          }
174 
175           ///   <param name="input"> 需要加密的明文 </param>
176           ///   <param name="key"> 密钥 </param>
177           ///   <returns> Message 密文 </returns>
178           public   static   byte [] Encrypt( byte [] input,  int  offset,  int  len,  byte [] key)
179          {
180              Crypter crypter  =   new  Crypter();
181              crypter.header  =   true ;
182               return  crypter.Encrypt0(input, offset, len, key);
183          }
184 
185           ///   <summary>
186           ///  抛出异常。
187           ///   </summary>
188           ///   <param name="message"> 异常信息 </param>
189           private   static   void  throwException( string  message)
190          {
191               throw   new  CrypterException(message);
192          }
193 
194           ///   <summary>  解密 </summary>
195           ///   <param name="input">
196           ///  密文
197           ///   </param>
198           ///   <param name="offset">
199           ///  密文开始的位置
200           ///   </param>
201           ///   <param name="len">
202           ///  密文长度
203           ///   </param>
204           ///   <param name="key">
205           ///  密钥
206           ///   </param>
207           ///   <returns>  明文
208           ///   </returns>
209           public   byte [] Decrypt0( byte [] input,  int  offset,  int  len,  byte [] key)
210          {
211              crypt  =  preCrypt  =   0 ;
212               this .key  =  key;
213               int  count;
214               byte [] m  =   new   byte [offset  +   8 ];
215 
216               //  因为QQ消息加密之后至少是16字节,并且肯定是8的倍数,这里检查这种情况
217               if  ((len  %   8   !=   0 ||  (len  <   16 ))
218                  throwException( @" len is not correct. " );
219               //  得到消息的头部,关键是得到真正明文开始的位置,这个信息存在第一个字节里面,所以其用解密得到的第一个字节与7做与
220              prePlain  =  Decipher(input, offset);
221              pos  =  prePlain[ 0 &   0x7 ;
222               //  得到真正明文的长度
223              count  =  len  -  pos  -   10 ;
224               //  如果明文长度小于0,那肯定是出错了,比如传输错误之类的,返回
225               if  (count  <   0 )
226                  throwException( @" count is not correct " );
227 
228               //  这个是临时的preCrypt,和加密时第一个8字节块没有prePlain一样,解密时
229               //      第一个8字节块也没有preCrypt,所有这里建一个全0的
230               for  ( int  i  =  offset; i  <  m.Length; i ++ )
231                  m[i]  =   0 ;
232               //  通过了上面的代码,密文应该是没有问题了,我们分配输出缓冲区
233              output  =   new   byte [count];
234               //  设置preCrypt的位置等于0,注意目前的preCrypt位置是指向m的,因为java没有指针,所以我们在后面要控制当前密文buf的引用
235              preCrypt  =   0 ;
236               //  当前的密文位置,为什么是8不是0呢?注意前面我们已经解密了头部信息了,现在当然该8了
237              crypt  =   8 ;
238               //  自然这个也是8
239              contextStart  =   8 ;
240               //  加1,和加密算法是对应的
241              pos ++ ;
242 
243               //  开始跳过头部,如果在这个过程中满了8字节,则解密下一块
244               //  因为是解密下一块,所以我们有一个语句 m = in,下一块当然有preCrypt了,我们不再用m了
245               //  但是如果不满8,这说明了什么?说明了头8个字节的密文是包含了明文信息的,当然还是要用m把明文弄出来
246               //  所以,很显然,满了8的话,说明了头8个字节的密文除了一个长度信息有用之外,其他都是无用的填充
247              padding  =   1 ;
248               while  (padding  <=   2 )
249              {
250                   if  (pos  <   8 )
251                  {
252                      pos ++ ;
253                      padding ++ ;
254                  }
255                   if  (pos  ==   8 )
256                  {
257                      m  =  input;
258                       if  ( ! Decrypt8Bytes(input, offset, len))
259                          throwException( @" Decrypt8Bytes() failed. " );
260                  }
261              }
262 
263               //  这里是解密的重要阶段,这个时候头部的填充都已经跳过了,开始解密
264               //  注意如果上面一个while没有满8,这里第一个if里面用的就是原始的m,否则这个m就是in了
265               int  i2  =   0 ;
266               while  (count  !=   0 )
267              {
268                   if  (pos  <   8 )
269                  {
270                      output[i2]  =  ( byte )(m[offset  +  preCrypt  +  pos]  ^  prePlain[pos]);
271                      i2 ++ ;
272                      count -- ;
273                      pos ++ ;
274                  }
275                   if  (pos  ==   8 )
276                  {
277                      m  =  input;
278                      preCrypt  =  crypt  -   8 ;
279                       if  ( ! Decrypt8Bytes(input, offset, len))
280                          throwException( @" Decrypt8Bytes() failed. " );
281                  }
282              }
283 
284               //  最后的解密部分,上面一个while已经把明文都解出来了,到了这里还剩下什么?对了,还剩下尾部的填充,应该全是0
285               //  所以这里有检查是否解密了之后是0,如果不是的话那肯定出错了,所以返回null
286               for  (padding  =   1 ; padding  <   8 ; padding ++ )
287              {
288                   if  (pos  <   8 )
289                  {
290                       if  ((m[offset  +  preCrypt  +  pos]  ^  prePlain[pos])  !=   0 )
291                          throwException( @" tail is not filled correct. " );
292                      pos ++ ;
293                  }
294                   if  (pos  ==   8 )
295                  {
296                      m  =  input;
297                      preCrypt  =  crypt;
298                       if  ( ! Decrypt8Bytes(input, offset, len))
299                          throwException( @" Decrypt8Bytes() failed. " );
300                  }
301              }
302               return  output;
303          }
304 
305           ///   <param name="input">
306           ///  需要被解密的密文
307           ///   </param>
308           ///   <param name="key">
309           ///  密钥
310           ///   </param>
311           ///   <returns>  Message 已解密的消息
312           ///   </returns>
313           public   byte [] Decrypt0( byte [] input,  byte [] key)
314          {
315               return  Decrypt(input,  0 , input.Length, key);
316          }
317 
318           ///   <summary> 加密 </summary>
319           ///   <param name="input"> 明文字节数组
320           ///   </param>
321           ///   <param name="offset"> 开始加密的偏移
322           ///   </param>
323           ///   <param name="len"> 加密长度
324           ///   </param>
325           ///   <param name="key"> 密钥
326           ///   </param>
327           ///   <returns>  密文字节数组
328           ///   </returns>
329           public   byte [] Encrypt0( byte [] input,  int  offset,  int  len,  byte [] key)
330          {
331              plain  =   new   byte [ 8 ];
332              prePlain  =   new   byte [ 8 ];
333              pos  =   1 ;
334              padding  =   0 ;
335              crypt  =  preCrypt  =   0 ;
336               this .key  =  key;
337              header  =   true ;
338            
339               //  计算头部填充字节数
340              pos  =  (len  +   0x0A %   8 ;
341               if  (pos  !=   0 )
342                  pos  =   8   -  pos;
343               //  计算输出的密文长度
344              output  =   new   byte [len  +  pos  +   10 ];
345               //  这里的操作把pos存到了plain的第一个字节里面
346               //      0xF8后面三位是空的,正好留给pos,因为pos是0到7的值,表示文本开始的字节位置
347               int  t1  =   0x7648354F ;
348 
349              plain[ 0 =  ( byte )((t1  &   0xF8 |  pos);
350 
351               //  这里用随机产生的数填充plain[1]到plain[pos]之间的内容
352               for  ( int  i  =   1 ; i  <=  pos; i ++ )
353                  plain[i]  =  ( byte )(t1   &   0xFF );
354              pos ++ ;
355               //  这个就是prePlain,第一个8字节块当然没有prePlain,所以我们做一个全0的给第一个8字节块
356               for  ( int  i  =   0 ; i  <   8 ; i ++ )
357                  prePlain[i]  =  ( byte )( 0x0 );
358 
359               //  继续填充2个字节的随机数,这个过程中如果满了8字节就加密之
360              padding  =   1 ;
361               while  (padding  <=   2 )
362              {
363                   if  (pos  <   8 )
364                  {
365                      plain[pos ++ =  ( byte )(t1  &   0xFF );
366                      padding ++ ;
367                  }
368                   if  (pos  ==   8 )
369                      Encrypt8Bytes();
370              }
371 
372               //  头部填充完了,这里开始填真正的明文了,也是满了8字节就加密,一直到明文读完
373               int  i2  =  offset;
374               while  (len  >   0 )
375              {
376                   if  (pos  <   8 )
377                  {
378                      plain[pos ++ =  input[i2 ++ ];
379                      len -- ;
380                  }
381                   if  (pos  ==   8 )
382                      Encrypt8Bytes();
383              }
384 
385               //  最后填上0,以保证是8字节的倍数
386              padding  =   1 ;
387               while  (padding  <=   7 )
388              {
389                   if  (pos  <   8 )
390                  {
391                      plain[pos ++ =  ( byte )( 0x0 );
392                      padding ++ ;
393                  }
394                   if  (pos  ==   8 )
395                      Encrypt8Bytes();
396              }
397 
398               return  output;
399          }
400 
401           ///   <param name="input">
402           ///  需要加密的明文
403           ///   </param>
404           ///   <param name="key">
405           ///  密钥
406           ///   </param>
407           ///   <returns>  Message 密文
408           ///   </returns>
409           public   byte [] Encrypt0( byte [] input,  byte [] key)
410          {
411               return  Encrypt(input,  0 , input.Length, key);
412          }
413 
414           ///   <summary>
415           ///  加密一个8字节块
416           ///   </summary>
417           ///   <param name="input">
418           ///  明文字节数组
419           ///   </param>
420           ///   <returns>
421           ///  密文字节数组
422           ///   </returns>
423           private   byte [] Encipher( byte [] input)
424          {
425               if  (key  ==   null )
426              {
427                  throwException( @" key is null. " );
428              }
429               //  迭代次数,16次
430               int  loop  =   0x10 ;
431               //  得到明文和密钥的各个部分,注意c#有无符号类型,所以为了表示一个无符号的整数
432               //  我们用了uint,这个uint的前32位是全0的,我们通过这种方式模拟无符号整数,后面用到的uint也都是一样的
433               //  而且为了保证前32位为0,需要和0xFFFFFFFF做一下位与            
434               uint  y  = GetUInt(input,  0 4 );
435               uint  z  = GetUInt(input,  4 4 );
436               uint  a  = GetUInt(key,  0 4 );
437               uint  b  = GetUInt(key,  4 4 );
438               uint  c  = GetUInt(key,  8 4 );
439               uint  d  = GetUInt(key,  12 4 );
440               //  这是算法的一些控制变量,为什么delta是0x9E3779B9呢?
441               //  这个数是TEA算法的delta,实际是就是sqr(5)-1 * 2^31
442               uint  sum  =   0 ;
443               uint  delta  =   0x9E3779B9 ;
444               // delta &= unchecked((int) 0xFFFFFFFFL);
445 
446               //  开始迭代了,乱七八糟的,我也看不懂,反正和DES之类的差不多,都是这样倒来倒去
447               while  (loop --   >   0 )
448              {
449                  sum  +=  delta;
450                   // sum &= unchecked((int) 0xFFFFFFFFL);
451                  y  +=  ((z  <<   4 +  a)  ^  (z  +  sum)  ^  (z  >>   5 +  b;
452                   // y &= unchecked((int) 0xFFFFFFFFL);
453                  z  +=  ((y  <<   4 +  c)  ^  (y  +  sum)  ^  (y  >>   5 +  d;
454                   // z &= unchecked((int) 0xFFFFFFFFL);
455              }
456 
457               //  最后,我们输出密文,因为我用的uint,所以需要强制转换一下变成int
458          
459               return  ToBytes(y, z);
460          }
461 
462           ///   <summary>
463           ///  解密从offset开始的8字节密文
464           ///   </summary>
465           ///   <param name="input">
466           ///  密文字节数组
467           ///   </param>
468           ///   <param name="offset">
469           ///  密文开始位置
470           ///   </param>
471           ///   <returns>
472           ///  明文
473           ///   </returns>
474           private   byte [] Decipher( byte [] input,  int  offset)
475          {
476               if  (key  ==   null )
477              {
478                  throwException( @" key is null. " );
479              }
480               //  迭代次数,16次
481               int  loop  =   0x10 ;
482               //  得到密文和密钥的各个部分,注意java没有无符号类型,所以为了表示一个无符号的整数
483               //  我们用了uint,这个uint的前32位是全0的,我们通过这种方式模拟无符号整数,后面用到的uint也都是一样的
484               //  而且为了保证前32位为0,需要和0xFFFFFFFF做一下位与
485               uint  y  = GetUInt(input, offset,  4 );
486               uint  z  = GetUInt(input, offset  +   4 4 );
487               uint  a  = GetUInt(key,  0 4 );
488               uint  b  = GetUInt(key,  4 4 );
489               uint  c  = GetUInt(key,  8 4 );
490               uint  d  = GetUInt(key,  12 4 );
491               //  算法的一些控制变量,为什么sum在这里也有数了呢,这个sum嘛就是和迭代次数有关系了
492               //  因为delta是这么多,所以sum如果是这么多的话,迭代的时候减减减,减16次,最后
493               //  得到什么? Yeah,得到0。反正这就是为了得到和加密时相反顺序的控制变量,这样
494               //  才能解密呀~~
495               uint  sum  =   0xE3779B90 ;
496               // sum &= unchecked((int) 0xFFFFFFFFL);
497               uint  delta  =   0x9E3779B9 ;
498               // delta &= unchecked((int) 0xFFFFFFFFL);
499 
500               //  迭代开始了, #_#
501               while  (loop --   >   0 )
502              {
503                  z  -=  ((y  <<   4 +  c)  ^  (y  +  sum)  ^  ((y  >>   5 +  d);
504                   // z &= unchecked((int) 0xFFFFFFFFL);
505                  y  -=  ((z  <<   4 +  a)  ^  (z  +  sum)  ^  ((z  >>   5 +  b);
506                   // y &= unchecked((int) 0xFFFFFFFFL);
507                  sum  -=  delta;
508                   // sum &= unchecked((int) 0xFFFFFFFFL);
509              }
510 
511               //  输出明文,注意要转成int
512        
513               return  ToBytes(y, z);
514          }
515 
516           ///   <summary>
517           ///  解密
518           ///   </summary>
519           ///   <param name="input">
520           ///  密文
521           ///   </param>
522           ///   <returns>
523           ///  明文
524           ///   </returns>
525           private   byte [] Decipher( byte [] input)
526          {
527               return  Decipher(input,  0 );
528          }
529 
530           ///   <summary>
531           ///  加密8字节
532           ///   </summary>
533           private   void  Encrypt8Bytes()
534          {
535               //  这部分完成我上面所说的 plain ^ preCrypt,注意这里判断了是不是第一个8字节块,如果是的话,那个prePlain就当作preCrypt用
536               for  (pos  =   0 ; pos  <   8 ; pos ++ )
537              {
538                   if  (header)
539                      plain[pos]  ^=  prePlain[pos];
540                   else
541                      plain[pos]  ^=  output[preCrypt  +  pos];
542              }
543               //  这个完成到了我上面说的 f(plain ^ preCrypt)
544               byte [] crypted  =  Encipher(plain);
545               //  这个没什么,就是拷贝一下,java不像c,所以我只好这么干,c就不用这一步了
546              Array.Copy(crypted,  0 , output, crypt,  8 );
547 
548               //  这个就是完成到了 f(plain ^ preCrypt) ^ prePlain,ok,完成了,下面拷贝一下就行了
549               for  (pos  =   0 ; pos  <   8 ; pos ++ )
550                  output[crypt  +  pos]  ^=  prePlain[pos];
551              Array.Copy(plain,  0 , prePlain,  0 8 );
552 
553               //  完成了加密,现在是调整crypt,preCrypt等等东西的时候了
554              preCrypt  =  crypt;
555              crypt  +=   8 ;
556              pos  =   0 ;
557              header  =   false ;
558          }
559 
560           ///   <summary>
561           ///  解密8个字节
562           ///   </summary>
563           ///   <param name="input">
564           ///  密文字节数组
565           ///   </param>
566           ///   <param name="offset">
567           ///  从何处开始解密
568           ///   </param>
569           ///   <param name="len">
570           ///  密文的长度
571           ///   </param>
572           ///   <returns>
573           ///  true表示解密成功
574           ///   </returns>
575           private   bool  Decrypt8Bytes( byte [] input,  int  offset,  int  len)
576          {
577               //  这里第一步就是判断后面还有没有数据,没有就返回,如果有,就执行 crypt ^ prePlain
578               for  (pos  =   0 ; pos  <   8 ; pos ++ )
579              {
580                   if  (contextStart  +  pos  >=  len)
581                       return   true ;
582                  prePlain[pos]  ^=  input[offset  +  crypt  +  pos];
583              }
584 
585               //  好,这里执行到了 d(crypt ^ prePlain)
586              prePlain  =  Decipher(prePlain);
587               if  (prePlain  ==   null )
588                   return   false ;
589 
590               //  解密完成,wait,没完成哦,最后一步没做哦? 
591               //  这里最后一步放到Decrypt里面去做了,因为解密的步骤毕竟还是不太一样嘛
592               //  调整这些变量的值先
593              contextStart  +=   8 ;
594              crypt  +=   8 ;
595              pos  =   0 ;
596               return   true ;
597          }
598 
599           ///   <summary>  
600           ///  这是个随机因子产生器,用来填充头部的,如果为了调试,可以用一个固定值。
601           ///  随机因子可以使相同的明文每次加密出来的密文都不一样。
602           ///   </summary>
603           ///   <returns>
604           ///  随机因子
605           ///   </returns>
606           private   int  Rand()
607          {
608               return  xRandom.Next();
609          }
610           static  Crypter()
611          {
612              random  = xRandom;
613          }
614      }
615 
616       ///   <summary>
617       ///  加密/解密出错异常。
618       ///   </summary>
619       public   class  CrypterException : Exception
620      {
621           public  CrypterException( string  message)
622              :  base (message)
623          {
624          }
625      }
626  }


 

转载于:https://www.cnblogs.com/ExeLive/archive/2008/03/07/1095130.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值