例一:简单加密
- public class A
- {
- public static void main(String[] args) throws Exception
- {
- String s = "我们abc";
- String key = "xyz";
- byte[] key_buf = key.getBytes("utf-8");
- //加密
- byte[] buf = s.getBytes("utf-8");
- for(int i=0; i<buf.length; i++){
- buf[i] ^= key_buf[i%key_buf.length];
- }
- // 解密
- for(int i=0; i<buf.length; i++){
- buf[i] ^= key_buf[i%key_buf.length];
- }
- System.out.println(new String(buf, "utf-8"));
- }
- }
例二:完整简单加密
- public class Simple
- {
- // buf 中的byte每个都转为16进制的串的表述形式
- static String byteToAF(byte[] buf)
- {
- StringBuffer sb = new StringBuffer();
- for(int i=0; i<buf.length; i++){
- sb.append(String.format("%02X",buf[i]));
- }
- return sb.toString();
- }
- // 用16进制串形式表达的 byte,转换为byte数组
- static byte[] AFtoByte(String s)
- {
- byte[] out = new byte[s.length()/2];
- for(int i=0; i<s.length(); i+=2){
- out[i/2] = (byte)(Character.getNumericValue(s.charAt(i)) * 16
- + Character.getNumericValue(s.charAt(i+1)));
- }
- return out;
- }
- // 加密过程
- static String encrypt(String src, String key)
- {
- if(key.length()<1) return null;
- try{
- byte[] buf_txt = src.getBytes("utf-8");
- byte[] buf_key = key.getBytes("utf-8");
- for(int i=0; i<buf_txt.length; i++){
- buf_txt[i] ^= buf_key[i%buf_key.length];
- }
- return byteToAF(buf_txt);
- }
- catch(Exception e){
- e.printStackTrace();
- }
- return null;
- }
- // 解密过程
- static String decrypt(String src, String key)
- {
- if(key.length()<1) return null;
- try{
- byte[] buf_txt = AFtoByte(src);
- byte[] buf_key = key.getBytes("utf-8");
- for(int i=0; i<buf_txt.length; i++){
- buf_txt[i] ^= buf_key[i%buf_key.length];
- }
- return new String(buf_txt,"utf-8");
- }
- catch(Exception e){
- e.printStackTrace();
- }
- return null;
- }
- public static void main(String[] args)
- {
- String s = encrypt("我们ab","xyz");
- System.out.println(s);
- String s2 = decrypt(s,"xyz");
- System.out.println(s2);
- }
- }
例三:AES加密
- import javax.crypto.*;
- import javax.crypto.spec.*;
- import java.security.*;
- import sun.misc.BASE64Decoder;
- import sun.misc.BASE64Encoder;
- public class AES
- {
- public static String encrypt(String src, String pwd)
- {
- try {
- // 处理密钥
- byte[] bKey = pwd.getBytes("utf-8");
- byte[] buf = new byte[16]; // 创建一个空的16位字节数组(默认值为0)
- for (int i = 0; i < bKey.length && i < buf.length; i++) {
- buf[i] = bKey[i];
- }
- SecretKeySpec key = new SecretKeySpec(buf, "AES");
- // 加密
- Cipher cipher = Cipher.getInstance("AES");// 创建密码器
- cipher.init(Cipher.ENCRYPT_MODE, key);
- byte[] out = cipher.doFinal(src.getBytes("utf-8"));
- //转为串
- return new BASE64Encoder().encode(out);
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- return "";
- }
- public static String decrypt(String src, String pwd)
- {
- try {
- // 处理密钥
- byte[] bKey = pwd.getBytes("utf-8");
- byte[] buf = new byte[16]; // 创建一个空的16位字节数组(默认值为0)
- for (int i = 0; i < bKey.length && i < buf.length; i++) {
- buf[i] = bKey[i];
- }
- SecretKeySpec key = new SecretKeySpec(buf, "AES");
- // 密文还原为byte[]
- buf = new BASE64Decoder().decodeBuffer(src);
- // 解密
- Cipher cipher = Cipher.getInstance("AES");// 创建密码器
- cipher.init(Cipher.DECRYPT_MODE, key);
- byte[] out = cipher.doFinal(buf);
- // 转为串
- return new String(out,"utf-8");
- }
- catch (Exception e) {
- e.printStackTrace();
- }
- return "";
- }
- public static void main(String[] args) throws Exception
- {
- String s = "1中国人abc";
- String s2 = encrypt(s,"xyz1");
- System.out.println(s2);
- String s3 = decrypt(s2,"xyz1");
- System.out.println(s3);
- }
- }
例四:
- /*设计程序
- 一种Playfair密码变种加密方法如下:首先选择一个密钥单词(称为pair)(字母不重复,且都为小写字母),然后与字母表中其他字母一起填入至一个5x5的方阵中,填入方法如下:
- 1.首先按行填入密钥串。
- 2.紧接其后,按字母序按行填入不在密钥串中的字母。
- 3.由于方阵中只有25个位置,最后剩下的那个字母则不需变换。
- 如果密钥为youandme,则该方阵如下:
- y o u a n
- d m e b c
- f g h i j
- k l p q r
- s t v w x
- 在加密一对字母时,如am,在方阵中找到以这两个字母为顶点的矩形(红色字体):
- y o u a n
- d m e b c
- f g h i j
- k l p q r
- s t v w x
- 这对字母的加密字母为该矩形的另一对顶点,如本例中为ob。
- 请设计程序,使用上述方法对输入串进行加密,并输出加密后的串。
- 另外有如下规定:
- 1、一对一对取字母,如果最后只剩下一个字母,则不变换,直接放入加密串中;
- 2、如果一对字母中的两个字母相同,则不变换,直接放入加密串中;
- 3、如果一对字母中有一个字母不在正方形中,则不变换,直接放入加密串中;
- 4、如果字母对出现在方阵中的同一行或同一列,如df或hi,则只需简单对调这两个字母,即变换为fd或ih;
- 5、如果在正方形中能够找到以字母对为顶点的矩形,假如字母对为am,则该矩形的另一对顶点字母中,与a同行的字母应在前面,在上例中应是ob;同样若待变换的字母对为ta,则变换后的字母对应为wo;
- 6、本程序中输入串均为小写字母,并不含标点、空格或其它字符。
- 解密方法与加密相同,即对加密后的字符串再加密,将得到原始串。
- 要求输入形式如下:
- 从控制台输入两行字符串,第一行为密钥单词(长度小于等于25),第二行为待加密字符串(长度小于等于50),两行字符串末尾都有一个回车换行符,并且两行字符串均为小写字母,不含其它字符。
- 在标准输出上输出加密后的字符串。
- 例如,若输入:
- youandme
- welcometohangzhou
- 则表示输入的密钥单词为youandme,形成的正方形如上所示;待加密字符串为welcometohangzhou。在正方形中可以找到以第一对字母we为顶点的矩形,对应另一对顶点字母为vb,因此加密后为vb,同理可找到与字母对lc,et,oh,ho对应的顶点字母对。而字母对om位于上述正方形中的同一列,所以直接以颠倒这两个字母来加密,即为mo,字母对an同理。字母对gz中的z不在上述正方形中,因此原样放到加密串中。最后剩一个字母u也原样输出。
- 因此输出的结果为:
- vbrmmomvugnagzguu*/
- public class C6 {
- static char [][] key = new char[5][5];//5x5的方阵
- static int [] alp = new int[26];//字母表,表示26个字母是否已经出现,-1表示没有出现过,i>-1表示已经出现,i/5为在方阵的横坐标,i%5为在方阵的纵坐标
- //将密匙转化为5x5的方阵
- public static void change(char []ckey) {
- for(int i = 0; i < 26; ++i)//字母表初始化
- alp[i] = -1;
- // 按行填入密钥串
- for (int ix = 0; ix < ckey.length; ++ix) {
- key[ix / 5][ix % 5] = ckey[ix];
- switch (ckey[ix]) {// 密钥中出现的字母,置为true
- case 'a':
- alp['a' - 'a'] = ix;
- break;
- case 'b':
- alp['b' - 'a'] = ix;
- break;
- case 'c':
- alp['c' - 'a'] = ix;
- break;
- case 'd':
- alp['d' - 'a'] = ix;
- break;
- case 'e':
- alp['e' - 'a'] = ix;
- break;
- case 'f':
- alp['f' - 'a'] = ix;
- break;
- case 'g':
- alp['g' - 'a'] = ix;
- break;
- case 'h':
- alp['h' - 'a'] = ix;
- break;
- case 'i':
- alp['i' - 'a'] = ix;
- break;
- case 'j':
- alp['j' - 'a'] = ix;
- break;
- case 'k':
- alp['k' - 'a'] = ix;
- break;
- case 'l':
- alp['l' - 'a'] = ix;
- break;
- case 'm':
- alp['m' - 'a'] = ix;
- break;
- case 'n':
- alp['n' - 'a'] = ix;
- break;
- case 'o':
- alp['o' - 'a'] = ix;
- break;
- case 'p':
- alp['p' - 'a'] = ix;
- break;
- case 'q':
- alp['q' - 'a'] = ix;
- break;
- case 'r':
- alp['r' - 'a'] = ix;
- break;
- case 's':
- alp['s' - 'a'] = ix;
- break;
- case 't':
- alp['t' - 'a'] = ix;
- break;
- case 'u':
- alp['u' - 'a'] = ix;
- break;
- case 'v':
- alp['v' - 'a'] = ix;
- break;
- case 'w':
- alp['w' - 'a'] = ix;
- break;
- case 'x':
- alp['x' - 'a'] = ix;
- break;
- case 'y':
- alp['y' - 'a'] = ix;
- break;
- case 'z':
- alp['z' - 'a'] = ix;
- break;
- default:
- break;
- }
- }
- // 紧接其后,按字母序按行填入不在密钥串中的字母
- for (int j = ckey.length, k = 0; j < 25 && k < 26; ++j, ++k) {
- // 不在密钥串中的字母
- if (alp[k] == -1) {
- key[j / 5][j % 5] = (char) (k + 'a');
- alp[k] = j;
- } else {
- j--;
- }
- }
- // 输出转化过 的5*5的矩阵
- for (int i = 0; i < 5; ++i) {
- for (int j = 0; j < 5; ++j) {
- System.out.print(key[i][j] + " ");
- }
- System.out.println();
- }
- }
- // 加密过程
- public static String encrypt (String pair, String s){
- // 处理密钥
- char []ckey = pair.toCharArray();//密匙
- change(ckey);//将密匙转化为5x5的方阵
- char [] c_s = s.toCharArray();
- //从待加密字符串取每对字母加密
- for(int i = 1; i < c_s.length; i += 2){//1
- //2如果一对字母中的两个字母相同,则不变换,直接放入加密串中;3或一对字母中有一个字母不在正方形中 时则不变换,直接放入加密串中
- if(c_s[i-1] == c_s[i] || (alp[c_s[i-1] - 'a'] == -1) || (alp[c_s[i] - 'a'] == -1))
- continue;
- //两个字母都在在正方形中且一对字母中的两个字母不同
- else {
- int row1 = alp[c_s[i-1] - 'a'] / 5;//一对字母中的第一个字母横坐标
- int clum1 = alp[c_s[i-1] - 'a'] % 5;//一对字母中的第一个字母纵坐标
- int row2 = alp[c_s[i] - 'a'] / 5;//一对字母中的第二个字母横坐标
- int clum2 = alp[c_s[i] - 'a'] % 5;//一对字母中的第二个字母纵坐标
- if(row1 == row2 || clum1 == clum2){//4如果字母对出现在方阵中的同一行或同一列,如df或hi,则只需简单对调这两个字母
- char temp = c_s[i-1];
- c_s[i-1] = c_s[i];
- c_s[i] = temp;
- }
- //5、如果在正方形中能够找到以字母对为顶点的矩形,假如字母对为am,则该矩形的另一对顶点字母中,与a同行的字母应在前面,
- //在上例中应是ob;同样若待变换的字母对为ta,则变换后的字母对应为wo;
- else{
- c_s[i-1] = key[row1][clum2];
- c_s[i] = key[row2][clum1];
- }
- }
- /* if(c_s.length % 2 == 1 && i == c_s.length ){
- break;
- }*/
- }
- String s2 = new String(c_s);//存储加密过的字符串
- return s2;
- }
- // 解密过程
- public static String decrypt (String pair, String s){
- // 处理密钥
- char []ckey = pair.toCharArray();//密匙
- change(ckey);//将密匙转化为5x5的方阵
- char [] c_s = s.toCharArray();
- //从待加密字符串取每对字母加密
- for(int i = 1; i < c_s.length; i += 2){//1
- //2如果一对字母中的两个字母相同,则不变换,直接放入加密串中;3或一对字母中有一个字母不在正方形中 时则不变换,直接放入加密串中
- if(c_s[i-1] == c_s[i] || (alp[c_s[i-1] - 'a'] == -1) || (alp[c_s[i] - 'a'] == -1))
- continue;
- //两个字母都在在正方形中且一对字母中的两个字母不同
- else {
- int row1 = alp[c_s[i-1] - 'a'] / 5;//一对字母中的第一个字母横坐标
- int clum1 = alp[c_s[i-1] - 'a'] % 5;//一对字母中的第一个字母纵坐标
- int row2 = alp[c_s[i] - 'a'] / 5;//一对字母中的第二个字母横坐标
- int clum2 = alp[c_s[i] - 'a'] % 5;//一对字母中的第二个字母纵坐标
- if(row1 == row2 || clum1 == clum2){//4如果字母对出现在方阵中的同一行或同一列,如df或hi,则只需简单对调这两个字母
- char temp = c_s[i-1];
- c_s[i-1] = c_s[i];
- c_s[i] = temp;
- }
- //5、如果在正方形中能够找到以字母对为顶点的矩形,假如字母对为am,则该矩形的另一对顶点字母中,与a同行的字母应在前面,
- //在上例中应是ob;同样若待变换的字母对为ta,则变换后的字母对应为wo;
- else{
- c_s[i-1] = key[row1][clum2];
- c_s[i] = key[row2][clum1];
- }
- }
- /* if(c_s.length % 2 == 1 && i == c_s.length ){
- break;
- }*/
- }
- String s2 = new String(c_s);//存储加密过的字符串
- return s2;
- }
- public static void main(String[] args) {
- String s;//待加密字符串
- String pair;//密匙
- Scanner scan = new Scanner(System.in);
- System.out.println("请输入两行字符串,第一行为密钥单词(长度小于等于25),第二行为待加密字符串(长度小于等于50):");
- pair = scan.nextLine();
- s = scan.nextLine();
- String s2 = encrypt(pair, s);
- String s3 = decrypt (pair, s2);
- System.out.println("加密过的字符串:");
- System.out.println(s2);
- System.out.println("解密过的字符串:");
- System.out.println(s3);
- }