zoukankan      html  css  js  c++  java
  • 工厂方法模式——java实现

    问题描述:

    目前常用的加密算法有DES(Data Encryption Standard)和IDEA(International Data Encryption Algorithm)国际数据加密算法等,请用工厂方法实现加密算法系统。

    类图:

     java源代码:

    //PWFactory.java
    public interface PWFactory {
        public PW producePW();
    } 
    //DESFactory.java
    public class DESFactory implements PWFactory{
        public PW producePW()
        {
            return new DES();
        }
    } 
    //IDEAFactory.java
    public class IDEAFactory implements PWFactory{
        public PW producePW()
        {
            return new IDEA();
        }
    } 
    //PW.java
    public interface PW {
        public void show();
    } 
    //DES.java
    import java.security.SecureRandom;
    import java.util.Scanner;
    import javax.crypto.Cipher;
    import javax.crypto.SecretKey;
    import javax.crypto.SecretKeyFactory; 
    import javax.crypto.spec.DESKeySpec;
    public class DES implements PW{
        public static byte[] encrypt(byte[] datasource, String password) {
            try {
                SecureRandom random = new SecureRandom();
                DESKeySpec desKey = new DESKeySpec(password.getBytes());
                SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
                SecretKey securekey = keyFactory.generateSecret(desKey);
                Cipher cipher = Cipher.getInstance("DES");
                cipher.init(Cipher.ENCRYPT_MODE, securekey, random);
                return cipher.doFinal(datasource);
            } catch (Throwable e) {
                e.printStackTrace();
            }
            return null;
        }
        public static byte[] decrypt(byte[] src, String password) throws Exception {
            SecureRandom random = new SecureRandom();
            DESKeySpec desKey = new DESKeySpec(password.getBytes());
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
            SecretKey securekey = keyFactory.generateSecret(desKey);
            Cipher cipher = Cipher.getInstance("DES");
            cipher.init(Cipher.DECRYPT_MODE, securekey, random);
            return cipher.doFinal(src);
        }
        public void show() {
            System.out.println("DES");
            System.out.print("请输入加密内容:");
            Scanner out = new Scanner(System.in);
            String str = out.nextLine();
            String password = "12345678";
            byte[] result = DES.encrypt(str.getBytes(), password);
            System.out.println("加密后:" + result);
            try {
                System.out.println("解密内容:"+result);
                byte[] decryResult = DES.decrypt(result, password);
                System.out.println("解密后:" + new String(decryResult));
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }    
    }
    //IDEA.java
    import java.security.SecureRandom;
    import java.util.Scanner;
    
    import javax.crypto.*;
    public class IDEA implements PW{
    private byte[] bytekey;
        public byte[] getKey(String key) { 
            int len1 = key.length();
            if (len1 >= 16) {
                key = key.substring(0, 16);
            } else {
                for (int i = 0; i < 16 - len1; i++) {
                    key = key.concat("0");
                }
            }
            bytekey = key.getBytes();
            return bytekey;
        }
        public String getEncString(String strMing) {
            byte[] byteMi = null;
            byte[] byteMing = null;
            String strMi = "";
            try {
                return byte2hex(IdeaEncrypt(bytekey, strMing.getBytes(), true));
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                byteMing = null;
                byteMi = null;
            }
            return strMi;
        }
        public String getDesString(String strMi,int l) {
            byte[] byteMing = null;
            byte[] byteMi = null;
            String strMing = "";
            try {
                String tmp = new String(IdeaEncrypt(bytekey, hex2byte(strMi.getBytes()), false));
                return tmp.substring(0, l);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                byteMing = null;
                byteMi = null;
            }
            return strMing;
        }
        private byte[] Encrypt(byte[] bytekey, byte[] inputBytes, boolean flag) {
            byte[] encryptCode = new byte[8];
            int[] key = get_subkey(flag, bytekey);
            encrypt(key, inputBytes, encryptCode);
            return encryptCode;
        }
        private int bytesToInt(byte[] inBytes, int startPos) {
            return ((inBytes[startPos] << 8) & 0xff00) + (inBytes[startPos + 1] & 0xff);
        }
        private void intToBytes(int inputInt, byte[] outBytes, int startPos) {
            outBytes[startPos] = (byte) (inputInt >>> 8);
            outBytes[startPos + 1] = (byte) inputInt;
        }
        private int x_multiply_y(int x, int y) {
            if (x == 0) {
                x = 0x10001 - y;
            } else if (y == 0) {
                x = 0x10001 - x;
            } else {
                int tmp = x * y;
                y = tmp & 0xffff;
                x = tmp >>> 16;
                x = (y - x) + ((y < x) ? 1 : 0);
            }
            return x & 0xffff;
        }
        private void encrypt(int[] key, byte[] inbytes, byte[] outbytes) {
            int k = 0;
            int a = bytesToInt(inbytes, 0);
            int b = bytesToInt(inbytes, 2);
            int c = bytesToInt(inbytes, 4);
            int d = bytesToInt(inbytes, 6);
            for (int i = 0; i < 8; i++) {
                a = x_multiply_y(a, key[k++]);
                b += key[k++];
                b &= 0xffff;
                c += key[k++];
                c &= 0xffff;
                d = x_multiply_y(d, key[k++]);
                int tmp1 = b;
                int tmp2 = c;
                c ^= a;
                b ^= d;
                c = x_multiply_y(c, key[k++]);
                b += c;
                b &= 0xffff;
                b = x_multiply_y(b, key[k++]);
                c += b;
                c &= 0xffff;
                a ^= b;
                d ^= c;
                b ^= tmp2;
                c ^= tmp1;
            }
            intToBytes(x_multiply_y(a, key[k++]), outbytes, 0);
            intToBytes(c + key[k++], outbytes, 2);
            intToBytes(b + key[k++], outbytes, 4);
            intToBytes(x_multiply_y(d, key[k]), outbytes, 6);
        }
        private int[] encrypt_subkey(byte[] byteKey) {
            int[] key = new int[52];
            if (byteKey.length < 16) {
                byte[] tmpkey = new byte[16];
                System.arraycopy(byteKey, 0, tmpkey, tmpkey.length - byteKey.length, byteKey.length);
                byteKey = tmpkey;
            }
            for (int i = 0; i < 8; i++) {
                key[i] = bytesToInt(byteKey, i * 2);
            }
            for (int j = 8; j < 52; j++) {
                if ((j & 0x7) < 6) {
                    key[j] = (((key[j - 7] & 0x7f) << 9) | (key[j - 6] >> 7)) & 0xffff;
                } else if ((j & 0x7) == 6) {
                    key[j] = (((key[j - 7] & 0x7f) << 9) | (key[j - 14] >> 7)) & 0xffff;
                } else {
                    key[j] = (((key[j - 15] & 0x7f) << 9) | (key[j - 14] >> 7)) & 0xffff;
                }
            }
            return key;
        }
        private int fun_a(int a) {
            if (a < 2) {
                return a;
            }
            int b = 1;
            int c = 0x10001 / a;
            for (int i = 0x10001 % a; i != 1;) {
                int d = a / i;
                a %= i;
                b = (b + (c * d)) & 0xffff;
                if (a == 1) {
                    return b;
                }
                d = i / a;
                i %= a;
                c = (c + (b * d)) & 0xffff;
            }
            return (1 - c) & 0xffff;
        }
        private int fun_b(int b) {
            return (0 - b) & 0xffff;
        }
        private int[] uncrypt_subkey(int[] key) {
            int dec = 52;
            int asc = 0;
            int[] unkey = new int[52];
            int aa = fun_a(key[asc++]);
            int bb = fun_b(key[asc++]);
            int cc = fun_b(key[asc++]);
            int dd = fun_a(key[asc++]);
            unkey[--dec] = dd;
            unkey[--dec] = cc;
            unkey[--dec] = bb;
            unkey[--dec] = aa;
            for (int k1 = 1; k1 < 8; k1++) {
                aa = key[asc++];
                bb = key[asc++];
                unkey[--dec] = bb;
                unkey[--dec] = aa;
                aa = fun_a(key[asc++]);
                bb = fun_b(key[asc++]);
                cc = fun_b(key[asc++]);
                dd = fun_a(key[asc++]);
                unkey[--dec] = dd;
                unkey[--dec] = bb;
                unkey[--dec] = cc;
                unkey[--dec] = aa;
            }
            aa = key[asc++];
            bb = key[asc++];
            unkey[--dec] = bb;
            unkey[--dec] = aa;
            aa = fun_a(key[asc++]);
            bb = fun_b(key[asc++]);
            cc = fun_b(key[asc++]);
            dd = fun_a(key[asc]);
            unkey[--dec] = dd;
            unkey[--dec] = cc;
            unkey[--dec] = bb;
            unkey[--dec] = aa;
            return unkey;
        }
        private int[] get_subkey(boolean flag, byte[] bytekey) {
            if (flag) {
                return encrypt_subkey(bytekey);
            } else {
                return uncrypt_subkey(encrypt_subkey(bytekey));
            }
        }
        private byte[] ByteDataFormat(byte[] data, int unit) {
            int len = data.length;
            int padlen = unit - (len % unit);
            int newlen = len + padlen;
            byte[] newdata = new byte[newlen];
            System.arraycopy(data, 0, newdata, 0, len);
            for (int i = len; i < newlen; i++)
                newdata[i] = (byte) padlen;
            return newdata;
        }
        public byte[] IdeaEncrypt(byte[] idea_key, byte[] idea_data, boolean flag) {
            byte[] format_key = ByteDataFormat(idea_key, 16);
            byte[] format_data = ByteDataFormat(idea_data, 8);
            int datalen = format_data.length;
            int unitcount = datalen / 8;
            byte[] result_data = new byte[datalen];
            for (int i = 0; i < unitcount; i++) {
                byte[] tmpkey = new byte[16];
                byte[] tmpdata = new byte[8];
                System.arraycopy(format_key, 0, tmpkey, 0, 16);
                System.arraycopy(format_data, i * 8, tmpdata, 0, 8);
                byte[] tmpresult = Encrypt(tmpkey, tmpdata, flag);
                System.arraycopy(tmpresult, 0, result_data, i * 8, 8);
            }
            return result_data;
        }
        public static String byte2hex(byte[] b) { // 一个字节的数,
                                                    // 转成16进制字符串
            String hs = "";
            String stmp = "";
            for (int n = 0; n < b.length; n++) {
                stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
                if (stmp.length() == 1)
                    hs = hs + "0" + stmp;
                else
                    hs = hs + stmp;
            }
            return hs.toUpperCase(); // 转成大写
        }
        public static byte[] hex2byte(byte[] b) {
            if ((b.length % 2) != 0)
                throw new IllegalArgumentException("长度不是偶数");
            byte[] b2 = new byte[b.length / 2];
            for (int n = 0; n < b.length; n += 2) {
                String item = new String(b, n, 2);
                b2[n / 2] = (byte) Integer.parseInt(item, 16);
            }
            return b2;
        }
        public void show() {
            System.out.println("IDEA");
            System.out.print("请输入加密内容:");
            Scanner out = new Scanner(System.in);
            String str = out.nextLine();
            IDEA idea = new IDEA();
            idea.getKey("aabb");// 生成密匙
            String strEnc = idea.getEncString(str);// 加密字符串,返回String的密文
            System.out.println("加密后:"+strEnc);
            int ll=str.length();
            System.out.println("解密内容:"+strEnc);
            String strDes = idea.getDesString(strEnc,ll);// 把String 类型的密文解密
            System.out.println("解密后:"+strDes);
        }
    }
    //main.java
    import java.util.Scanner;
    
    public class main {
        public static void main(String[] args) {
            try{ 
                PW pw;
                PWFactory mif = null;
                System.out.println("请选择:1、DES算法  2、IDEA算法");
                Scanner input=new Scanner(System.in);
                int i=input.nextInt();
                if(i==1) {
                    mif=new DESFactory();
                }else if(i==2) {
                    mif=new IDEAFactory();
                }else {
                    System.out.println("输入无效!");
                }
                pw=mif.producePW();
                pw.show();
            }
            catch(Exception e)
            {
                System.out.println(e.getMessage());
            }
        }
    }

     运行结果:

    DES:

    IDEA:

  • 相关阅读:
    Swift编码总结4
    Swift编码总结3
    无题
    WebSocket桌面客户端工具
    Dell U2913WM使用感受
    Oracle DB 12c first glance
    [翻译] Oracle Database 12c 新特性Multitenant
    一眨眼oracle 12c也有了
    .Net内存泄露原因及解决办法
    .NET 强引用和弱引用
  • 原文地址:https://www.cnblogs.com/znjy/p/14167022.html
Copyright © 2011-2022 走看看