package com.qmth.qrzk.repository.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import org.apache.commons.io.IOUtils;

public class DESCoder {

	private static byte[] Key = {37, 45, 71, 120, 92, 32, 65, 98 };
//	private static byte[] IV = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
	
	public static byte[] desDecrypt(byte[] bytes) throws Exception {
		Cipher cipher = Cipher.getInstance("DES/ECB/NoPadding");
		DESKeySpec desKeySpec = new DESKeySpec(Key);

		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
		// IvParameterSpec iv = new IvParameterSpec(IV);
		cipher.init(Cipher.DECRYPT_MODE, secretKey);

		byte[] output = cipher.doFinal(bytes);
		return output;
	}
	
	private static Cipher initCipher(boolean isDecrypt) throws NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeyException, InvalidKeySpecException{
		Cipher cipher = Cipher.getInstance("DES/ECB/PKCS5Padding");
		DESKeySpec desKeySpec = new DESKeySpec(Key);

		SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
		SecretKey secretKey = keyFactory.generateSecret(desKeySpec);
		// IvParameterSpec iv = new IvParameterSpec(IV);
		cipher.init(isDecrypt?Cipher.DECRYPT_MODE:Cipher.ENCRYPT_MODE, secretKey);
		return cipher;
	}
	
	 /** 
     * <p> DES解密文件 
     * @param file 需要解密的文件 
     * @param dest 解密后的文件 
	 * @throws InvalidKeySpecException 
	 * @throws NoSuchPaddingException 
	 * @throws NoSuchAlgorithmException 
	 * @throws InvalidKeyException 
	 * @throws IOException 
	 * @throws Exception 
     */  
    public static void decrypt(File file, File dest) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, IOException{  
        Cipher cipher = initCipher(true);
        InputStream is = null;
        OutputStream out = null;
        CipherOutputStream cos = null;
        try {
	        is = new FileInputStream(file);  
	        out = new FileOutputStream(dest);  
	        cos = new CipherOutputStream(out, cipher);
	        IOUtils.copyLarge(is, cos);
//	        byte[] buffer = new byte[1024*10];  
//	        int r;  
//	        while ((r = is.read(buffer)) >= 0) {  
//	            cos.write(buffer, 0, r);  
//	        }
	        cos.flush();
	        out.flush();
		}finally {
			General.close(cos);
			General.close(out);
			General.close(is);
		}
    }  
    /** 
     * <p>DES加密文件 
     * @param file 源文件 
     * @param destFile 加密后的文件 
     * @throws InvalidKeySpecException 
     * @throws NoSuchPaddingException 
     * @throws NoSuchAlgorithmException 
     * @throws InvalidKeyException 
     * @throws IOException 
     * @throws Exception 
     */  
    public static void encrypt(File file, File destFile) throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, IOException{  
    	Cipher cipher = initCipher(false);
        InputStream is = null;
        OutputStream out = null;
        CipherInputStream cis = null;
        try {
	        is = new FileInputStream(file);  
	        out = new FileOutputStream(destFile);  
	        cis = new CipherInputStream(is, cipher);
	        IOUtils.copyLarge(cis, out);
//	        byte[] buffer = new byte[1024*10];  
//	        int r;  
//	        while ((r = cis.read(buffer)) > 0) {  
//	            out.write(buffer, 0, r);  
//	        }
	        out.flush();
        }finally {
			General.close(out);
			General.close(cis);
			General.close(is);
		}
    }
    
    public static void main(String[] args) {
    	try {
//    		File resFile = new File("D:/tmp/20170701_client_20171021.zip");
//    		File encFile = new File("D:/tmp/20170701_client_20171021_enc.data");
//    		File decFile = new File("D:/tmp/20170701_client_20171021_dec.zip");
//    		encrypt(resFile,encFile);
//    		System.out.println("加密完成。");
//    		decrypt(encFile, decFile);
//    		System.out.println("解密完成。");
    		
    		File encFile = new File("D:/tmp/20170701_client_20171024.qrzk");
    		File decFile = new File("D:/tmp/20170701_client_20171024.qrzk.zip");
    		decrypt(encFile, decFile);
    		System.out.println("解密完成。");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}
