package cydar;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
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.Key;

import javax.crypto.Cipher;
import javax.crypto.spec.SecretKeySpec;

public class FileCoder {

	private static final String algorithm = "AES";
	private static final String transformation = algorithm + "/ECB/PKCS5Padding";
	
	private Key key;

	public FileCoder(Key key) {
		this.key = key;
	}
	
	/**
	 * <p>¿øº» ÆÄÀÏÀ» ¾ÏÈ£È­ÇØ¼­ ´ë»ó ÆÄÀÏÀ» ¸¸µç´Ù.</p>
	 * 
	 * @param source ¿øº» ÆÄÀÏ
	 * @param dest ´ë»ó ÆÄÀÏ
	 * @throws Exception
	 */
	public void encrypt(File source, File dest) throws Exception {
		crypt(Cipher.ENCRYPT_MODE, source, dest);
	}
	
	/**
	 * <p>¿øº» ÆÄÀÏÀ» º¹È£È­ÇØ¼­ ´ë»ó ÆÄÀÏÀ» ¸¸µç´Ù.</p>
	 * 
	 * @param source ¿øº» ÆÄÀÏ
	 * @param dest ´ë»ó ÆÄÀÏ
	 * @throws Exception
	 */
	public void decrypt(File source, File dest) throws Exception {
		crypt(Cipher.DECRYPT_MODE, source, dest);
	}
	
	/**
	 * <p>¿øº» ÆÄÀÏÀ» ¾Ï/º¹È£È­ÇØ¼­ ´ë»ó ÆÄÀÏÀ» ¸¸µç´Ù.</p>
	 * 
	 * @param mode ¾Ï/º¹È£È­ ¸ðµå
	 * @param source ¿øº» ÆÄÀÏ
	 * @param dest ´ë»ó ÆÄÀÏ
	 * @throws Exception
	 */
	private void crypt(int mode, File source, File dest) throws Exception {
		Cipher cipher = Cipher.getInstance(transformation);
		cipher.init(mode, key);
		InputStream input = null;
		OutputStream output = null;
		try {
			input = new BufferedInputStream(new FileInputStream(source));
			output = new BufferedOutputStream(new FileOutputStream(dest));
			byte[] buffer = new byte[1024];
			int read = -1;
			while ((read = input.read(buffer)) != -1) {
				output.write(cipher.update(buffer, 0, read));
			}
			output.write(cipher.doFinal());
		} finally {
			if (output != null) {
				try { output.close(); } catch(IOException ie) {}
			}
			if (input != null) {
				try { input.close(); } catch(IOException ie) {}
			}
		}
	}
	
	public static void main(String[] args) throws Exception {
		// 128ºñÆ®ÀÇ Å°
		SecretKeySpec key = new SecretKeySpec(toBytes("696d697373796f7568616e6765656e61", 16), algorithm);
		FileCoder coder = new FileCoder(key);
		coder.encrypt(new File("C:/ASLog_0.txt"), new File("C:/ASLog_0_E.txt"));
		coder.decrypt(new File("C:/ASLog_0_E.txt"), new File("C:/ASLog_0_D.txt"));
	}
	
	/**
	 * <p>¹®ÀÚ¿­À» ¹ÙÀÌÆ®¹è¿­·Î ¹Ù²Û´Ù.</p>
	 * 
	 * @param digits ¹®ÀÚ¿­
	 * @param radix Áø¼ö
	 * @return
	 * @throws IllegalArgumentException
	 * @throws NumberFormatException
	 */
	public static byte[] toBytes(String digits, int radix) throws IllegalArgumentException, NumberFormatException {
		if (digits == null) {
			return null;
		}
		if (radix != 16 && radix != 10 && radix != 8) {
			throw new IllegalArgumentException("For input radix: \"" + radix + "\"");
		}
		int divLen = (radix == 16) ? 2 : 3;
    	int length = digits.length();
    	if (length % divLen == 1) {
    		throw new IllegalArgumentException("For input string: \"" + digits + "\"");
    	}
    	length = length / divLen;
    	byte[] bytes = new byte[length];
    	for (int i = 0; i < length; i++) {
    		int index = i * divLen;
    		bytes[i] = (byte)(Short.parseShort(digits.substring(index, index+divLen), radix));
    	}
    	return bytes;
	}
	

}
