一些可逆算法汇集(一)

3 篇文章 0 订阅

COPY的资料:

微型加密算法(TEA)及其相关变种(XTEA,Block TEA,XXTEA) 都是分组加密算法,它们很容易被描述,实现也很简单(典型的几行代码)。
TEA 算法最初是由剑桥计算机实验室的 David Wheeler 和 Roger Needham 在 1994 年设计的。该算法使用 128 位的密钥为 64 位的信息块进行加密,它需要进行 64 轮迭代,尽管作者认为 32 轮已经足够了。该算法使用了一个神秘常数δ作为倍数,它来源于黄金比率,以保证每一轮加密都不相同。但δ的精确值似乎并不重要,这里 TEA 把它定义为 δ=「(√5 - 1)231」(也就是程序中的 0×9E3779B9)。之后 TEA 算法被发现存在缺陷,作为回应,设计者提出了一个 TEA 的升级版本——XTEA(有时也被称为“tean”)。XTEA 跟 TEA 使用了相同的简单运算,但它采用了截然不同的顺序,为了阻止密钥表攻击,四个子密钥(在加密过程中,原 128 位的密钥被拆分为 4 个 32 位的子密钥)采用了一种不太正规的方式进行混合,但速度更慢了。
在跟描述 XTEA 算法的同一份报告中,还介绍了另外一种被称为 Block TEA 算法的变种,它可以对 32 位大小任意倍数的变量块进行操作。该算法将 XTEA 轮循函数依次应用于块中的每个字,并且将它附加于它的邻字。该操作重复多少轮依赖于块的大小,但至少需要 6 轮。该方法的优势在于它无需操作模式(CBC,OFB,CFB 等),密钥可直接用于信息。对于长的信息它可能比 XTEA 更有效率。
在 1998 年,Markku-Juhani Saarinen 给出了一个可有效攻击 Block TEA 算法的代码,但之后很快 David J. Wheeler 和 Roger M. Needham 就给出了 Block TEA 算法的修订版,这个算法被称为 XXTEA。XXTEA 使用跟 Block TEA 相似的结构,但在处理块中每个字时利用了相邻字。它利用一个更复杂的 MX 函数代替了 XTEA 轮循函数,MX 使用 2 个输入量。

 

XXTEA算法在加密、解密时需要提供给算法一个自己设计的密码本,此密码本必须严密保护,不可对外泄露,可以是任意字符,甚至可以是中文。

 

C#实现:

  1. /* xxtea.cs
  2.  *
  3.  * Author:       Ma Bingyao <andot@ujn.edu.cn>
  4.  * Copyright:    CoolCode.CN
  5.  * Version:      1.1
  6.  * LastModified: 2006-05-05
  7.  * This library is free.  You can redistribute it and/or modify it.
  8.  * http://www.coolcode.cn/?p=163
  9.  */
  10. using System;
  11. class XXTEA
  12. {
  13.     public static Byte[] Encrypt(Byte[] Data, Byte[] Key)
  14.     {
  15.         if (Data.Length == 0)
  16.         {
  17.             return Data;
  18.         }
  19.         return ToByteArray(Encrypt(ToUInt32Array(Data, true), ToUInt32Array(Key, false)), false);
  20.     }
  21.     public static Byte[] Decrypt(Byte[] Data, Byte[] Key)
  22.     {
  23.         if (Data.Length == 0)
  24.         {
  25.             return Data;
  26.         }
  27.         return ToByteArray(Decrypt(ToUInt32Array(Data, false), ToUInt32Array(Key, false)), true);
  28.     }
  29.     public static UInt32[] Encrypt(UInt32[] v, UInt32[] k)
  30.     {
  31.         Int32 n = v.Length - 1;
  32.         if (n < 1)
  33.         {
  34.             return v;
  35.         }
  36.         if (k.Length < 4)
  37.         {
  38.             UInt32[] Key = new UInt32[4];
  39.             k.CopyTo(Key, 0);
  40.             k = Key;
  41.         }
  42.         UInt32 z = v[n], y = v[0], delta = 0x9E3779B9, sum = 0, e;
  43.         Int32 p, q = 6 + 52 / (n + 1);
  44.         while (q-- > 0)
  45.         {
  46.             sum = unchecked(sum + delta);
  47.             e = sum >> 2 & 3;
  48.             for (p = 0; p < n; p++)
  49.             {
  50.                 y = v[p + 1];
  51.                 z = unchecked(v[p] += (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));
  52.             }
  53.             y = v[0];
  54.             z = unchecked(v[n] += (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));
  55.         }
  56.         return v;
  57.     }
  58.     public static UInt32[] Decrypt(UInt32[] v, UInt32[] k)
  59.     {
  60.         Int32 n = v.Length - 1;
  61.         if (n < 1)
  62.         {
  63.             return v;
  64.         }
  65.         if (k.Length < 4)
  66.         {
  67.             UInt32[] Key = new UInt32[4];
  68.             k.CopyTo(Key, 0);
  69.             k = Key;
  70.         }
  71.         UInt32 z = v[n], y = v[0], delta = 0x9E3779B9, sum, e;
  72.         Int32 p, q = 6 + 52 / (n + 1);
  73.         sum = unchecked((UInt32)(q * delta));
  74.         while (sum != 0)
  75.         {
  76.             e = sum >> 2 & 3;
  77.             for (p = n; p > 0; p--)
  78.             {
  79.                 z = v[p - 1];
  80.                 y = unchecked(v[p] -= (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));
  81.             }
  82.             z = v[n];
  83.             y = unchecked(v[0] -= (z >> 5 ^ y << 2) + (y >> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z));
  84.             sum = unchecked(sum - delta);
  85.         }
  86.         return v;
  87.     }
  88.     //
  89.     private static UInt32[] ToUInt32Array(Byte[] Data, Boolean IncludeLength)
  90.     {
  91.         //将加密字节根据长度进行位移运算得出&3的key
  92.         Int32 n = (((Data.Length & 3) == 0) ? (Data.Length >> 2) : ((Data.Length >> 2) + 1));
  93.         UInt32[] Result;
  94.         
  95.         if (IncludeLength)
  96.         {
  97.             Result = new UInt32[n + 1];
  98.             Result[n] = (UInt32)Data.Length;
  99.         }
  100.         else
  101.         {
  102.             Result = new UInt32[n];
  103.         }
  104.         n = Data.Length;
  105.         for (Int32 i = 0; i < n; i++)
  106.         {
  107.             Result[i >> 2] |= (UInt32)Data[i] << ((i & 3) << 3);
  108.         }
  109.         return Result;
  110.     }
  111.     private static Byte[] ToByteArray(UInt32[] Data, Boolean IncludeLength)
  112.     {
  113.         Int32 n;
  114.         if (IncludeLength)
  115.         {
  116.             n = (Int32)Data[Data.Length - 1];
  117.         }
  118.         else
  119.         {
  120.             n = Data.Length << 2;
  121.         }
  122.         Byte[] Result = new Byte[n];
  123.         for (Int32 i = 0; i < n; i++)
  124.         {
  125.             Result[i] = (Byte)(Data[i >> 2] >> ((i & 3) << 3));
  126.         }
  127.         return Result;
  128.     }
  129. }

JS实现:

  1. /* xxtea.js
  2. *
  3. * Author: Ma Bingyao <andot@ujn.edu.cn>
  4. * Copyright: CoolCode.CN
  5. * Version: 1.2
  6. * LastModified: 2006-05-02
  7. * This library is free. You can redistribute it and/or modify it.
  8. * http://www.coolcode.cn/?p=128
  9. */ 
  10. function long2str(v, w) {
  11. var vl = v.length;
  12. var sl = v[vl - 1] & 0xffffffff;
  13. for (var i = 0; i < vl; i++)
  14. {
  15. v[i] = String.fromCharCode(v[i] & 0xff,
  16. v[i] >>> 8 & 0xff,
  17. v[i] >>> 16 & 0xff, 
  18. v[i] >>> 24 & 0xff);
  19. }
  20. if (w) {
  21. return v.join('').substring(0, sl);
  22. }
  23. else {
  24. return v.join('');
  25. }
  26. }
  27. function str2long(s, w) {
  28. var len = s.length;
  29. var v = [];
  30. for (var i = 0; i < len; i += 4)
  31. {
  32. v[i >> 2] = s.charCodeAt(i)
  33. | s.charCodeAt(i + 1) << 8
  34. | s.charCodeAt(i + 2) << 16
  35. | s.charCodeAt(i + 3) << 24;
  36. }
  37. if (w) {
  38. v[v.length] = len;
  39. }
  40. return v;
  41. }
  42. function xxtea_encrypt(str, key) {
  43. if (str == "") {
  44. return "";
  45. }
  46. var v = str2long(str, true);
  47. var k = str2long(key, false);
  48. var n = v.length - 1;
  49. var z = v[n], y = v[0], delta = 0x9E3779B9;
  50. var mx, e, q = Math.floor(6 + 52 / (n + 1)), sum = 0;
  51. while (q-- > 0) {
  52. sum = sum + delta & 0xffffffff;
  53. e = sum >>> 2 & 3;
  54. for (var p = 0; p < n; p++) {
  55. y = v[p + 1];
  56. mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
  57. z = v[p] = v[p] + mx & 0xffffffff;
  58. }
  59. y = v[0];
  60. mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
  61. z = v[n] = v[n] + mx & 0xffffffff;
  62. }
  63. return long2str(v, false);
  64. }
  65. function xxtea_decrypt(str, key) {
  66. if (str == "") {
  67. return "";
  68. }
  69. var v = str2long(str, false);
  70. var k = str2long(key, false);
  71. var n = v.length - 1;
  72. var z = v[n - 1], y = v[0], delta = 0x9E3779B9;
  73. var mx, e, q = Math.floor(6 + 52 / (n + 1)), sum = q * delta & 0xffffffff;
  74. while (sum != 0) {
  75. e = sum >>> 2 & 3;
  76. for (var p = n; p > 0; p--) {
  77. z = v[p - 1];
  78. mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
  79. y = v[p] = v[p] - mx & 0xffffffff;
  80. }
  81. z = v[n];
  82. mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
  83. y = v[0] = v[0] - mx & 0xffffffff;
  84. sum = sum - delta & 0xffffffff;
  85. }
  86. return long2str(v, true);
  87. }

Java实现:

  1. /* xxtea.java 
  2. * Author:       Ma Bingyao < andot@ujn.edu.cn > 
  3. * Copyright:    CoolCode.CN 
  4. * Version:      1.0 
  5. * LastModified: 2006-05-11 
  6. * This library is free.  You can redistribute it and/or modify it. 
  7. * http://www.coolcode.cn/?p=169 
  8. */ 
  9. public   class xxtea { 
  10.     /** 
  11.      * Encrypt data with key. 
  12.      * 
  13.      * @param data 
  14.      * @param key 
  15.      * @return 
  16.      */ 
  17.     public   static byte [] encrypt ( byte [] data , byte [] key ) { 
  18.         if   ( data . length == 0 ) { 
  19.             return   data ; 
  20.         } 
  21.         return   toByteArray ( encrypt ( toIntArray ( data , true ) , toIntArray ( key , false )) , false ) ; 
  22.     } 
  23.   
  24.     /** 
  25.      * Decrypt data with key. 
  26.      * 
  27.      * @param data 
  28.      * @param key 
  29.      * @return 
  30.      */ 
  31.     public   static byte [] decrypt ( byte [] data , byte [] key ) { 
  32.         if   ( data . length == 0 ) { 
  33.             return   data ; 
  34.         } 
  35.         return   toByteArray ( decrypt ( toIntArray ( data , false ) , toIntArray ( key , false )) , true ) ; 
  36.     } 
  37.   
  38.     /** 
  39.      * Encrypt data with key. 
  40.      * 
  41.      * @param v 
  42.      * @param k 
  43.      * @return 
  44.      */ 
  45.     public   static int [] encrypt ( int [] v , int [] k ) { 
  46.         int   n = v . length - 1 ; 
  47.         if   ( n < 1 ) { 
  48.             return   v ; 
  49.         } 
  50.         if   ( k . length < 4 ) { 
  51.             int []   key = new int [ 4 ] ; 
  52.             System . arraycopy ( k , 0 , key , 0 , k . length ) ; 
  53.             k = key ; 
  54.         } 
  55.         int   z = v [ n ] , y = v [ 0 ] , delta = 0x9E3779B9 , sum = 0 , e ; 
  56.         int   p , q = 6 + 52 / ( n + 1 ) ; 
  57.         while   ( q -- > 0 ) { 
  58.             sum = sum + delta ; 
  59.             e = sum >>> 2 & 3 ; 
  60.             for   ( p = 0 ; p < n ; p ++ ) { 
  61.                 y = v [ p + 1 ] ; 
  62.                 z = v [ p ] += ( z >>> 5 ^ y << 2 ) + ( y >>> 3 ^ z << 4 ) ^ ( sum ^ y ) + ( k [ p & 3 ^ e ] ^ z ) ; 
  63.             } 
  64.             y = v [ 0 ] ; 
  65.             z = v [ n ] += ( z >>> 5 ^ y << 2 ) + ( y >>> 3 ^ z << 4 ) ^ ( sum ^ y ) + ( k [ p & 3 ^ e ] ^ z ) ; 
  66.         } 
  67.         return   v ; 
  68.     } 
  69.   
  70.     /** 
  71.      * Decrypt data with key. 
  72.      * 
  73.      * @param v 
  74.      * @param k 
  75.      * @return 
  76.      */ 
  77.     public   static int [] decrypt ( int [] v , int [] k ) { 
  78.         int   n = v . length - 1 ; 
  79.         if   ( n < 1 ) { 
  80.             return   v ; 
  81.         } 
  82.         if   ( k . length < 4 ) { 
  83.             int []   key = new int [ 4 ] ; 
  84.             System . arraycopy ( k , 0 , key , 0 , k . length ) ; 
  85.             k = key ; 
  86.         } 
  87.         int   z = v [ n ] , y = v [ 0 ] , delta = 0x9E3779B9 , sum , e ; 
  88.         int   p , q = 6 + 52 / ( n + 1 ) ; 
  89.         sum = q * delta ; 
  90.         while   ( sum != 0 ) { 
  91.             e = sum >>> 2 & 3 ; 
  92.             for   ( p = n ; p > 0 ; p -- ) { 
  93.                 z = v [ p - 1 ] ; 
  94.                 y = v [ p ] -= ( z >>> 5 ^ y << 2 ) + ( y >>> 3 ^ z << 4 ) ^ ( sum ^ y ) + ( k [ p & 3 ^ e ] ^ z ) ; 
  95.             } 
  96.             z = v [ n ] ; 
  97.             y = v [ 0 ] -= ( z >>> 5 ^ y << 2 ) + ( y >>> 3 ^ z << 4 ) ^ ( sum ^ y ) + ( k [ p & 3 ^ e ] ^ z ) ; 
  98.             sum = sum - delta ; 
  99.         } 
  100.         return   v ; 
  101.     } 
  102.   
  103.     /** 
  104.      * Convert byte array to int array. 
  105.      * 
  106.      * @param data 
  107.      * @param includeLength 
  108.      * @return 
  109.      */ 
  110.     private   static int [] toIntArray ( byte [] data , boolean includeLength ) { 
  111.         int   n = ((( data . length & 3 ) == 0 ) ? ( data . length >>> 2 ) 
  112.                 : (( data . length >>> 2 ) + 1 )) ; 
  113.         int []   result ; 
  114.         if   ( includeLength ) { 
  115.             result = new   int [ n + 1 ] ; 
  116.             result [ n ] = data . length ; 
  117.         }   else { 
  118.             result = new   int [ n ] ; 
  119.         } 
  120.         n = data . length ; 
  121.         for   ( int i = 0 ; i < n ; i ++ ) { 
  122.             result [ i >>> 2 ] |= ( 0x000000ff & data [ i ]) << (( i & 3 ) << 3 ) ; 
  123.         } 
  124.         return   result ; 
  125.     } 
  126.   
  127.     /** 
  128.      * Convert int array to byte array. 
  129.      * 
  130.      * @param data 
  131.      * @param includeLength 
  132.      * @return 
  133.      */ 
  134.     private   static byte [] toByteArray ( int [] data , boolean includeLength ) { 
  135.         int   n ; 
  136.         if   ( includeLength ) { 
  137.             n = data [ data . length - 1 ] ; 
  138.         }   else { 
  139.             n = data . length << 2 ; 
  140.         } 
  141.   
  142.         byte []   result = new byte [ n ] ; 
  143.         for   ( int i = 0 ; i < n ; i ++ ) { 
  144.             result [ i ] = ( byte )   ( data [ i >>> 2 ] >>> (( i & 3 ) << 3 )) ; 
  145.         } 
  146.         return   result ; 
  147.     } 
  148. }

AS3实现:

 package com.klstudio.crypto{
       
        import com.klstudio.util.StringUtil;
       
        public class XXTEA{
               
                public function XXTEA(){
                        throw new Error("XXTEA class is static container only");
                }
               
                private static function long2str(v:Array,w:Boolean):String {
                        var vl:uint = v.length;
                        var sl = v[vl - 1] & 0xffffffff;
                        for (var i:uint = 0; i < vl; i++){
                                v[i] = String.fromCharCode(v[i] & 0xff,
                                                           v[i] >>> 8 & 0xff,
                                v[i] >>> 16 & 0xff,
                                v[i] >>> 24 & 0xff);
                        }
                        if(w){
                                return v.join('').substring(0, sl);
                        }
                        else {
                                return v.join('');
                        }
                }
               
                private static function str2long(s:String,w:Boolean):Array {
                        var len:uint = s.length;
                        var v:Array = new Array();
                        for (var i:uint = 0; i < len; i += 4){
                                v[i >> 2] = s.charCodeAt(i)
                                | s.charCodeAt(i + 1) << 8
                                | s.charCodeAt(i + 2) << 16
                                | s.charCodeAt(i + 3) << 24;
                        }
                        if (w) {
                                v[v.length] = len;
                        }
                        return v;
                }
               
                public static function encrypt(char:String,key:String):String{
                        if(char == ""){
                                return "";
                        }
                        var v:Array = str2long(StringUtil.utf16to8(char), true);
                        var k:Array = str2long(key, false);
                        var n:uint = v.length - 1;
                       
                        var z:Number = v[n];
                        var y:Number = v[0];
                        var delta:Number = 0x9E3779B9;
                        var mx:Number;
                        var q:Number = Math.floor(6 + 52 / (n + 1))
                        var sum:Number = 0;
                        while (q-- > 0) {
                                sum = sum + delta & 0xffffffff;
                                var e:Number = sum >>> 2 & 3;
                                for (var p:uint = 0; p < n; p++) {
                                        y = v[p + 1];
                                        mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
                                        z = v[p] = v[p] + mx & 0xffffffff;
                                }
                                y = v[0];
                                mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
                                z = v[n] = v[n] + mx & 0xffffffff;
                        }
                        return long2str(v, false);
                }
               
                public static function decrypt(char:String,key:String):String{
                        if (char == "") {
                                return "";
                        }
                        var v:Array = str2long(char, false);
                        var k:Array = str2long(key, false);
                        var n:uint = v.length - 1;
                       
                        var z:Number = v[n - 1];
                        var y:Number = v[0];
                        var delta:Number = 0x9E3779B9;
                        var mx:Number;
                        var q:Number = Math.floor(6 + 52 / (n + 1));
                        var sum:Number = q * delta & 0xffffffff;
                        while (sum != 0) {
                                var e:Number = sum >>> 2 & 3;
                                for (var p:uint = n; p > 0; p--) {
                                        z = v[p - 1];
                                        mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
                                        y = v[p] = v[p] - mx & 0xffffffff;
                                }
                                z = v[n];
                                mx = (z >>> 5 ^ y << 2) + (y >>> 3 ^ z << 4) ^ (sum ^ y) + (k[p & 3 ^ e] ^ z);
                                y = v[0] = v[0] - mx & 0xffffffff;
                                sum = sum - delta & 0xffffffff;
                        }
                       
                        return StringUtil.utf8to16(long2str(v, true));
                }
        }
}

 

 

以C#实现为例,调用加解密类操作时:

1)加密:

  1. .........
  2. //欲加密字符串
  3. String str = "我要加密";
  4. //密码本
  5. String encryptionStr = "你真的要加密吗?";
  6. //得到encoder对象
  7. System.Text.Encoding encoder = System.Text.Encoding.UTF8;
  8. //使用XXTEA加密类对输入字符串进行加密,得到加密后的字节数组(字节数组,字节数组)
  9. Byte[] data = XXTEA.Encrypt(encoder.GetBytes(str), encoder.GetBytes(encryptionStr;
  10. //将加密后的字节数组转换为等效字符串
  11. String decryptStr = System.Convert.ToBase64String(data);
  12. .........

2)解密:

  1. .........
  2. //得到encoder对象
  3.             System.Text.Encoding encoder = System.Text.Encoding.UTF8;
  4.             //欲解密字符串 
  5.             String decryptStr = "这里是加密得到的decryptStr字符串";
  6.             //密码本 
  7.             String encryptionStr = "你真的要加密吗?";
  8.             //解密后的字符串
  9.             String str = "";
  10.             try
  11.             {
  12.                 //通过XXTEA解密类将加密字符串解密
  13.                 str = encoder.GetString(XXTEA.Decrypt(System.Convert.FromBase64String(decryptStr), encoder.GetBytes(encryptionStr)));
  14.             }
  15.             catch (Exception e)
  16.             {
  17.                throw new Exception("这个字符不可解密!");
  18.             }
  19. .........

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值