算法基础——2.6加密与解密

例一:简单加密

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class A  
  2. {  
  3.     public static void main(String[] args) throws Exception  
  4.     {  
  5.         String s = "我们abc";  
  6.         String key = "xyz";  
  7.           
  8.         byte[] key_buf = key.getBytes("utf-8");  
  9.           
  10.         //加密  
  11.         byte[] buf = s.getBytes("utf-8");  
  12.         for(int i=0; i<buf.length; i++){  
  13.             buf[i] ^= key_buf[i%key_buf.length];   
  14.         }  
  15.           
  16.         // 解密  
  17.         for(int i=0; i<buf.length; i++){  
  18.             buf[i] ^= key_buf[i%key_buf.length];   
  19.         }  
  20.           
  21.                   
  22.         System.out.println(new String(buf, "utf-8"));  
  23.     }  
  24. }  

例二:完整简单加密

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. public class Simple  
  2. {  
  3.     // buf 中的byte每个都转为16进制的串的表述形式  
  4.     static String byteToAF(byte[] buf)  
  5.     {  
  6.         StringBuffer sb = new StringBuffer();  
  7.         for(int i=0; i<buf.length; i++){  
  8.             sb.append(String.format("%02X",buf[i]));  
  9.         }  
  10.         return sb.toString();  
  11.     }  
  12.       
  13.     // 用16进制串形式表达的 byte,转换为byte数组  
  14.     static byte[] AFtoByte(String s)  
  15.     {  
  16.         byte[] out = new byte[s.length()/2];  
  17.           
  18.         for(int i=0; i<s.length(); i+=2){  
  19.             out[i/2] = (byte)(Character.getNumericValue(s.charAt(i)) * 16  
  20.                 + Character.getNumericValue(s.charAt(i+1)));  
  21.         }   
  22.           
  23.         return out;  
  24.     }  
  25.       
  26.     // 加密过程  
  27.     static String encrypt(String src, String key)  
  28.     {  
  29.         if(key.length()<1return null;  
  30.         try{  
  31.             byte[] buf_txt = src.getBytes("utf-8");  
  32.             byte[] buf_key = key.getBytes("utf-8");  
  33.               
  34.             for(int i=0; i<buf_txt.length; i++){  
  35.                 buf_txt[i] ^= buf_key[i%buf_key.length];  
  36.             }  
  37.               
  38.             return byteToAF(buf_txt);  
  39.               
  40.         }  
  41.         catch(Exception e){  
  42.             e.printStackTrace();  
  43.         }  
  44.         return null;  
  45.     }  
  46.       
  47.     // 解密过程  
  48.     static String decrypt(String src, String key)  
  49.     {  
  50.         if(key.length()<1return null;  
  51.         try{  
  52.             byte[] buf_txt = AFtoByte(src);  
  53.             byte[] buf_key = key.getBytes("utf-8");  
  54.               
  55.             for(int i=0; i<buf_txt.length; i++){  
  56.                 buf_txt[i] ^= buf_key[i%buf_key.length];  
  57.             }  
  58.               
  59.             return new String(buf_txt,"utf-8");  
  60.               
  61.         }  
  62.         catch(Exception e){  
  63.             e.printStackTrace();  
  64.         }  
  65.         return null;  
  66.           
  67.     }  
  68.       
  69.     public static void main(String[] args)  
  70.     {  
  71.         String s = encrypt("我们ab","xyz");  
  72.         System.out.println(s);  
  73.               
  74.         String s2 = decrypt(s,"xyz");  
  75.         System.out.println(s2);       
  76.     }  
  77. }  

例三:AES加密

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. import javax.crypto.*;  
  2. import javax.crypto.spec.*;  
  3. import java.security.*;  
  4.   
  5. import sun.misc.BASE64Decoder;  
  6. import sun.misc.BASE64Encoder;  
  7.   
  8.   
  9. public class AES  
  10. {  
  11.       
  12.     public static String encrypt(String src, String pwd)   
  13.     {    
  14.         try {  
  15.             // 处理密钥  
  16.             byte[] bKey = pwd.getBytes("utf-8");  
  17.             byte[] buf = new byte[16]; // 创建一个空的16位字节数组(默认值为0)  
  18.       
  19.             for (int i = 0; i < bKey.length && i < buf.length; i++) {  
  20.                 buf[i] = bKey[i];  
  21.             }  
  22.             SecretKeySpec key = new SecretKeySpec(buf, "AES");   
  23.               
  24.             // 加密  
  25.             Cipher cipher = Cipher.getInstance("AES");// 创建密码器  
  26.             cipher.init(Cipher.ENCRYPT_MODE, key);  
  27.             byte[] out = cipher.doFinal(src.getBytes("utf-8"));  
  28.               
  29.             //转为串  
  30.             return new BASE64Encoder().encode(out);  
  31.         }   
  32.         catch (Exception e) {  
  33.             e.printStackTrace();  
  34.         }    
  35.   
  36.         return "";  
  37.     }  
  38.       
  39.     public static String decrypt(String src, String pwd)   
  40.     {    
  41.         try {  
  42.             // 处理密钥  
  43.             byte[] bKey = pwd.getBytes("utf-8");  
  44.             byte[] buf = new byte[16]; // 创建一个空的16位字节数组(默认值为0)  
  45.       
  46.             for (int i = 0; i < bKey.length && i < buf.length; i++) {  
  47.                 buf[i] = bKey[i];  
  48.             }  
  49.             SecretKeySpec key = new SecretKeySpec(buf, "AES");   
  50.               
  51.             // 密文还原为byte[]  
  52.             buf = new BASE64Decoder().decodeBuffer(src);  
  53.               
  54.             // 解密  
  55.             Cipher cipher = Cipher.getInstance("AES");// 创建密码器  
  56.             cipher.init(Cipher.DECRYPT_MODE, key);  
  57.             byte[] out = cipher.doFinal(buf);  
  58.               
  59.             // 转为串  
  60.             return new String(out,"utf-8");  
  61.         }   
  62.         catch (Exception e) {  
  63.             e.printStackTrace();  
  64.         }    
  65.   
  66.         return "";  
  67.     }  
  68.       
  69.     public static void main(String[] args) throws Exception  
  70.     {  
  71.         String s = "1中国人abc";  
  72.           
  73.         String s2 = encrypt(s,"xyz1");  
  74.           
  75.         System.out.println(s2);  
  76.           
  77.         String s3 = decrypt(s2,"xyz1");  
  78.           
  79.         System.out.println(s3);  
  80.     }  
  81. }  

例四:

[java]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. /*设计程序 
  2. 一种Playfair密码变种加密方法如下:首先选择一个密钥单词(称为pair)(字母不重复,且都为小写字母),然后与字母表中其他字母一起填入至一个5x5的方阵中,填入方法如下: 
  3. 1.首先按行填入密钥串。 
  4. 2.紧接其后,按字母序按行填入不在密钥串中的字母。 
  5. 3.由于方阵中只有25个位置,最后剩下的那个字母则不需变换。 
  6. 如果密钥为youandme,则该方阵如下: 
  7. y o u a n 
  8. d m e b c 
  9. f g h i j 
  10. k l p q r 
  11. s t v w x 
  12. 在加密一对字母时,如am,在方阵中找到以这两个字母为顶点的矩形(红色字体): 
  13. y o u a n 
  14. d m e b c 
  15. f g h i j 
  16. k l p q r 
  17. s t v w x 
  18. 这对字母的加密字母为该矩形的另一对顶点,如本例中为ob。 
  19. 请设计程序,使用上述方法对输入串进行加密,并输出加密后的串。 
  20. 另外有如下规定: 
  21. 1、一对一对取字母,如果最后只剩下一个字母,则不变换,直接放入加密串中; 
  22. 2、如果一对字母中的两个字母相同,则不变换,直接放入加密串中; 
  23. 3、如果一对字母中有一个字母不在正方形中,则不变换,直接放入加密串中; 
  24. 4、如果字母对出现在方阵中的同一行或同一列,如df或hi,则只需简单对调这两个字母,即变换为fd或ih; 
  25. 5、如果在正方形中能够找到以字母对为顶点的矩形,假如字母对为am,则该矩形的另一对顶点字母中,与a同行的字母应在前面,在上例中应是ob;同样若待变换的字母对为ta,则变换后的字母对应为wo; 
  26. 6、本程序中输入串均为小写字母,并不含标点、空格或其它字符。 
  27. 解密方法与加密相同,即对加密后的字符串再加密,将得到原始串。 
  28. 要求输入形式如下: 
  29. 从控制台输入两行字符串,第一行为密钥单词(长度小于等于25),第二行为待加密字符串(长度小于等于50),两行字符串末尾都有一个回车换行符,并且两行字符串均为小写字母,不含其它字符。 
  30. 在标准输出上输出加密后的字符串。 
  31. 例如,若输入: 
  32. youandme 
  33. welcometohangzhou 
  34. 则表示输入的密钥单词为youandme,形成的正方形如上所示;待加密字符串为welcometohangzhou。在正方形中可以找到以第一对字母we为顶点的矩形,对应另一对顶点字母为vb,因此加密后为vb,同理可找到与字母对lc,et,oh,ho对应的顶点字母对。而字母对om位于上述正方形中的同一列,所以直接以颠倒这两个字母来加密,即为mo,字母对an同理。字母对gz中的z不在上述正方形中,因此原样放到加密串中。最后剩一个字母u也原样输出。 
  35. 因此输出的结果为: 
  36. vbrmmomvugnagzguu*/  
  37.   
  38. public class C6 {  
  39.     static char [][] key = new char[5][5];//5x5的方阵  
  40.     static int [] alp = new int[26];//字母表,表示26个字母是否已经出现,-1表示没有出现过,i>-1表示已经出现,i/5为在方阵的横坐标,i%5为在方阵的纵坐标  
  41.       
  42.     //将密匙转化为5x5的方阵  
  43.     public static void change(char []ckey) {  
  44.         for(int i = 0; i < 26; ++i)//字母表初始化  
  45.             alp[i] = -1;  
  46.           
  47.         // 按行填入密钥串  
  48.         for (int ix = 0; ix < ckey.length; ++ix) {  
  49.             key[ix / 5][ix % 5] = ckey[ix];  
  50.             switch (ckey[ix]) {// 密钥中出现的字母,置为true  
  51.             case 'a':  
  52.                 alp['a' - 'a'] = ix;  
  53.                 break;  
  54.             case 'b':  
  55.                 alp['b' - 'a'] = ix;  
  56.                 break;  
  57.             case 'c':  
  58.                 alp['c' - 'a'] = ix;  
  59.                 break;  
  60.             case 'd':  
  61.                 alp['d' - 'a'] = ix;  
  62.                 break;  
  63.             case 'e':  
  64.                 alp['e' - 'a'] = ix;  
  65.                 break;  
  66.             case 'f':  
  67.                 alp['f' - 'a'] = ix;  
  68.                 break;  
  69.             case 'g':  
  70.                 alp['g' - 'a'] = ix;  
  71.                 break;  
  72.             case 'h':  
  73.                 alp['h' - 'a'] = ix;  
  74.                 break;  
  75.             case 'i':  
  76.                 alp['i' - 'a'] = ix;  
  77.                 break;  
  78.             case 'j':  
  79.                 alp['j' - 'a'] = ix;  
  80.                 break;  
  81.             case 'k':  
  82.                 alp['k' - 'a'] = ix;  
  83.                 break;  
  84.             case 'l':  
  85.                 alp['l' - 'a'] = ix;  
  86.                 break;  
  87.             case 'm':  
  88.                 alp['m' - 'a'] = ix;  
  89.                 break;  
  90.             case 'n':  
  91.                 alp['n' - 'a'] = ix;  
  92.                 break;  
  93.             case 'o':  
  94.                 alp['o' - 'a'] = ix;  
  95.                 break;  
  96.             case 'p':  
  97.                 alp['p' - 'a'] = ix;  
  98.                 break;  
  99.             case 'q':  
  100.                 alp['q' - 'a'] = ix;  
  101.                 break;  
  102.             case 'r':  
  103.                 alp['r' - 'a'] = ix;  
  104.                 break;  
  105.             case 's':  
  106.                 alp['s' - 'a'] = ix;  
  107.                 break;  
  108.             case 't':  
  109.                 alp['t' - 'a'] = ix;  
  110.                 break;  
  111.             case 'u':  
  112.                 alp['u' - 'a'] = ix;  
  113.                 break;  
  114.             case 'v':  
  115.                 alp['v' - 'a'] = ix;  
  116.                 break;  
  117.             case 'w':  
  118.                 alp['w' - 'a'] = ix;  
  119.                 break;  
  120.             case 'x':  
  121.                 alp['x' - 'a'] = ix;  
  122.                 break;  
  123.             case 'y':  
  124.                 alp['y' - 'a'] = ix;  
  125.                 break;  
  126.             case 'z':  
  127.                 alp['z' - 'a'] = ix;  
  128.                 break;  
  129.             default:  
  130.                 break;  
  131.             }  
  132.         }  
  133.         // 紧接其后,按字母序按行填入不在密钥串中的字母  
  134.         for (int j = ckey.length, k = 0; j < 25 && k < 26; ++j, ++k) {  
  135.             // 不在密钥串中的字母  
  136.             if (alp[k] == -1) {  
  137.                 key[j / 5][j % 5] = (char) (k + 'a');  
  138.                 alp[k] = j;  
  139.             } else {  
  140.                 j--;  
  141.             }  
  142.         }  
  143.   
  144.         // 输出转化过 的5*5的矩阵  
  145.         for (int i = 0; i < 5; ++i) {  
  146.             for (int j = 0; j < 5; ++j) {  
  147.                 System.out.print(key[i][j] + " ");  
  148.             }  
  149.             System.out.println();  
  150.         }  
  151.     }  
  152.       
  153.     // 加密过程  
  154.     public static String encrypt (String pair, String s){  
  155.         // 处理密钥  
  156.         char []ckey = pair.toCharArray();//密匙  
  157.         change(ckey);//将密匙转化为5x5的方阵  
  158.           
  159.           
  160.         char [] c_s = s.toCharArray();  
  161.         //从待加密字符串取每对字母加密  
  162.         for(int i = 1; i < c_s.length; i += 2){//1  
  163.             //2如果一对字母中的两个字母相同,则不变换,直接放入加密串中;3或一对字母中有一个字母不在正方形中 时则不变换,直接放入加密串中  
  164.             if(c_s[i-1] == c_s[i] || (alp[c_s[i-1] - 'a'] == -1) || (alp[c_s[i] - 'a'] == -1))  
  165.                 continue;  
  166.             //两个字母都在在正方形中且一对字母中的两个字母不同  
  167.             else {  
  168.                 int row1 = alp[c_s[i-1] - 'a'] / 5;//一对字母中的第一个字母横坐标  
  169.                 int clum1 = alp[c_s[i-1] - 'a'] % 5;//一对字母中的第一个字母纵坐标  
  170.                 int row2 = alp[c_s[i] - 'a'] / 5;//一对字母中的第二个字母横坐标  
  171.                 int clum2 = alp[c_s[i] - 'a'] % 5;//一对字母中的第二个字母纵坐标  
  172.                   
  173.                 if(row1 == row2 || clum1 == clum2){//4如果字母对出现在方阵中的同一行或同一列,如df或hi,则只需简单对调这两个字母  
  174.                     char temp = c_s[i-1];  
  175.                     c_s[i-1] = c_s[i];  
  176.                     c_s[i] = temp;  
  177.                 }  
  178.                 //5、如果在正方形中能够找到以字母对为顶点的矩形,假如字母对为am,则该矩形的另一对顶点字母中,与a同行的字母应在前面,  
  179.                 //在上例中应是ob;同样若待变换的字母对为ta,则变换后的字母对应为wo;  
  180.                 else{  
  181.                     c_s[i-1] = key[row1][clum2];  
  182.                     c_s[i] = key[row2][clum1];  
  183.                 }  
  184.             }  
  185. /*          if(c_s.length % 2 == 1 && i == c_s.length ){ 
  186.                 break; 
  187.             }*/  
  188.         }  
  189.       
  190.         String s2 = new String(c_s);//存储加密过的字符串  
  191.         return s2;  
  192.     }  
  193.       
  194.     // 解密过程  
  195.     public static String decrypt (String pair, String s){  
  196.         // 处理密钥  
  197.         char []ckey = pair.toCharArray();//密匙  
  198.         change(ckey);//将密匙转化为5x5的方阵  
  199.           
  200.         char [] c_s = s.toCharArray();  
  201.         //从待加密字符串取每对字母加密  
  202.         for(int i = 1; i < c_s.length; i += 2){//1  
  203.             //2如果一对字母中的两个字母相同,则不变换,直接放入加密串中;3或一对字母中有一个字母不在正方形中 时则不变换,直接放入加密串中  
  204.             if(c_s[i-1] == c_s[i] || (alp[c_s[i-1] - 'a'] == -1) || (alp[c_s[i] - 'a'] == -1))  
  205.                 continue;  
  206.             //两个字母都在在正方形中且一对字母中的两个字母不同  
  207.             else {  
  208.                 int row1 = alp[c_s[i-1] - 'a'] / 5;//一对字母中的第一个字母横坐标  
  209.                 int clum1 = alp[c_s[i-1] - 'a'] % 5;//一对字母中的第一个字母纵坐标  
  210.                 int row2 = alp[c_s[i] - 'a'] / 5;//一对字母中的第二个字母横坐标  
  211.                 int clum2 = alp[c_s[i] - 'a'] % 5;//一对字母中的第二个字母纵坐标  
  212.                   
  213.                 if(row1 == row2 || clum1 == clum2){//4如果字母对出现在方阵中的同一行或同一列,如df或hi,则只需简单对调这两个字母  
  214.                     char temp = c_s[i-1];  
  215.                     c_s[i-1] = c_s[i];  
  216.                     c_s[i] = temp;  
  217.                 }  
  218.                 //5、如果在正方形中能够找到以字母对为顶点的矩形,假如字母对为am,则该矩形的另一对顶点字母中,与a同行的字母应在前面,  
  219.                 //在上例中应是ob;同样若待变换的字母对为ta,则变换后的字母对应为wo;  
  220.                 else{  
  221.                     c_s[i-1] = key[row1][clum2];  
  222.                     c_s[i] = key[row2][clum1];  
  223.                 }  
  224.             }  
  225. /*          if(c_s.length % 2 == 1 && i == c_s.length ){ 
  226.                 break; 
  227.             }*/  
  228.         }  
  229.       
  230.         String s2 = new String(c_s);//存储加密过的字符串  
  231.         return s2;  
  232.   
  233.     }  
  234.       
  235.     public static void main(String[] args) {  
  236.         String s;//待加密字符串  
  237.         String pair;//密匙  
  238.         Scanner scan = new Scanner(System.in);  
  239.         System.out.println("请输入两行字符串,第一行为密钥单词(长度小于等于25),第二行为待加密字符串(长度小于等于50):");  
  240.         pair = scan.nextLine();  
  241.         s = scan.nextLine();  
  242.           
  243.         String s2 = encrypt(pair, s);  
  244.         String s3 = decrypt (pair, s2);  
  245.         System.out.println("加密过的字符串:");  
  246.         System.out.println(s2);  
  247.         System.out.println("解密过的字符串:");  
  248.         System.out.println(s3);  
  249.           
  250.     }  
  251.   
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值