http://blog.sina.com.cn/s/blog_532af66a0100a1lq.html
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
public class ChgAnGo {
// log4jのプロパティフィアル名
private static String LOG_PROPERTIES = "log4j.properties";
// パスワードファイルパス
private static String PASSWORD_FILEPATH = "output/password.txt";
// 反転用文字入力ファイルパス
private static String CONVERT_FILEPATH = "input/convert.txt";
// ログメッセージ:暗号化処理開始
private static String LOG_ENCRYPT_START = "文字列の暗号化開始";
// ログメッセージ:暗号化処理完了
private static String LOG_ENCRYPT_END = "文字列の暗号化完了";
// ログメッセージ:暗号化処理前
private static String LOG_ENCRYPT_BEFORE = "暗号化処理前:";
// ログメッセージ:暗号化処理後
private static String LOG_ENCRYPT_AFTER = "暗号化処理後:";
//反転用文字を取得できない場合
private static String LOG_CONVERT_KEY_READ_ERROR = "暗号化のキーワードの取得に失敗しました。";
//ファイルに出力失敗場合
private static String LOG_FILE_WRITE_ERROR = "暗号化したパスワードのファイル出力に失敗しました。";
// コンソールメッセージ:入力メッセージ
private static String CONSOLE_INPUT_MESSAGE = "暗号化したいパスワードを入力してください。";
// コンソールメッセージ:入力した文字列バイト数>40場合
private static String CONSOLE_INPUT_COUNT_ERROR = "エラー:40バイト以内文字列を入力してください。";
// コンソールメッセージ:半角英数字、半角記号以外が入力された場合
private static String CONSOLE_INPUT_CHAR_ERROR = "エラー:半角英数字、半角記号を入力してください。";
// コンソールメッセージ:ファイルに出力失敗場合
private static String CONSOLE_FILE_WRITE_ERROR = "エラー:暗号化したパスワードをファイルに出力するのは失敗しました。";
// コンソールメッセージ:反転用文字入力ファイルを取得できない場合
private static String CONSOLE_CONVERT_KEY_READ_ERROR = "エラー:暗号化のキーワードの取得に失敗しました。";
// コンソールメッセージ:暗号化成功場合
private static String CONSOLE_SUCCESS_END = "暗号化したパスワードはoutput/password.txtに出力しました。";
// コンソールメッセージ:プログラム終了
private static String CONSOLE_END = "処理終了しました。";
// ログを出力するために、loggerを取得
private static Logger logger = Logger.getLogger(ChgAnGo.class.getName());
public static void main(String[] args) {
ChgAnGo chgAnGo = new ChgAnGo();
//log4jプロパティファイルを取得する
PropertyConfigurator.configure(LOG_PROPERTIES);
//処理開始ログ出力
logger.info(LOG_ENCRYPT_START);
try {
//暗号化したい文字列
String inStr = "";
//暗号化したい文字列の取得
//コマンドラインから入力した引数が存在(args.length==1)場合
if (args.length == 1) {
inStr = args[0];
} else {
//コマンドラインから入力した引数が不存在(args.length<>1)場合
// byte[] input = new byte[41];
//スクリーンへメッセージを出力する。
System.out.println(CONSOLE_INPUT_MESSAGE);
//スクリーンから暗号化したい文字列を取得する。
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
inStr = br.readLine();
}
// 文字列のチェック
//入力した文字列バイト数>40場合
if (inStr.getBytes().length > 40) {
System.out.println(CONSOLE_INPUT_COUNT_ERROR);
} else if (inStr.getBytes().length > inStr.length()) {
// 半角英数字、半角記号以外が入力された場合
System.out.println(CONSOLE_INPUT_CHAR_ERROR);
} else if ("".equals(inStr)) {
//何も入力しない場合
System.out.println(CONSOLE_INPUT_CHAR_ERROR);
} else {
//上記以外場合、文字列に暗号化処理
//暗号化のキーワードの取得
String cstrKey = chgAnGo.getConvertKey(CONVERT_FILEPATH);
if (cstrKey != null && !"".equals(cstrKey)) {
//暗号化処理メソッドを呼び出す
String ango = chgAnGo.setEncrypt(inStr, cstrKey);
//暗号化した文字列をファイルに出力する。
chgAnGo.writeToFile(PASSWORD_FILEPATH, ango.getBytes());
//正常終了時、ログを出力する。
logger.info(LOG_ENCRYPT_BEFORE + inStr);
logger.info(LOG_ENCRYPT_AFTER + ango);
//スクリーンへメッセージを出力する。
System.out.println(CONSOLE_SUCCESS_END);
System.out.println(chgAnGo.getEncrypt(ango, cstrKey));
} else {
//反転用文字を取得できない場合、ログを出力する。
logger.info(LOG_CONVERT_KEY_READ_ERROR);
//スクリーンへメッセージを出力する。
System.out.println(CONSOLE_CONVERT_KEY_READ_ERROR);
}
}
} catch (IOException e) {
//例外エラー発生場合、詳細エラーを出力する。
logger.fatal(e.getMessage());
} finally {
//処理完了ログ出力
//スクリーンへメッセージを出力する
System.out.println(CONSOLE_END);
//「文字列の暗号化完了」ログを出力する。
logger.info(LOG_ENCRYPT_END);
}
}
protected String setEncrypt(String password, String cstrKey) {
//int[] snNum = new int[password.length()];
char[] snNum = new char[password.length()];
String result = "";
//ビット反転操作を繰り回す
for (int i = 0, j = 0; i < password.length(); i++, j++) {
//反転用文字列」<「暗号化したい文字列」場合、
//反転用文字列を繰り回して利用する
if (j == cstrKey.length())
j = 0;
//暗号化したバイト=(暗号化したい文字)^(反転用文字)^(1/(当該文字の位置+1))
//snNum[i] = password.charAt(i) ^ cstrKey.charAt(j) ^ (1 / (i + 1));
snNum[i] = (char) (password.charAt(i) ^ cstrKey.charAt(j) ^ (1 / (i + 1)));
result += (char) snNum[i];
}
//暗号化した文字列を返す。
return result;
}
protected String getEncrypt(String password, String cstrKey) {
char[] snNum = new char[password.length()];
String result = "";
//ビット反転操作を繰り回す
for (int i = 0, j = 0; i < password.length(); i++, j++) {
//反転用文字列」<「復号化したい文字列」場合、
//反転用文字列を繰り回して利用する
if (j == cstrKey.length())
j = 0;
char n = password.charAt(i);
//復号化したバイト=(復号化したい文字)^(反転用文字)^(1/(当該文字の位置+1))
snNum[i] = (char) (n ^ cstrKey.charAt(j) ^ (1 / (i + 1)));
result += snNum[i];
}
//復号化した文字列を返す。
return result;
}
protected void writeToFile(String filePath, byte[] data) throws IOException {
FileOutputStream outfile = null;
try {
//ファイルパスより、出力ファイルを開く
outfile = new FileOutputStream(filePath);
//データをファイルに出力する
outfile.write(data, 0, data.length);
//ファイルを保存する
outfile.flush();
} catch (IOException e) {
//ファイル出力失敗場合、ログを出力する。
logger.info(LOG_FILE_WRITE_ERROR);
//スクリーンへメッセージを出力する。
System.out.println(CONSOLE_FILE_WRITE_ERROR);
throw e;
} finally {
//ファイルをクローズする
if (outfile != null) {
outfile.close();
}
}
}
protected String getConvertKey(String filePath) throws IOException {
String convertKey = null;
BufferedReader br = null;
try {
//ファイルパスより、入力ファイルを開く
br = new BufferedReader(new FileReader(filePath));
//反転用文字を取得する
convertKey = br.readLine();
//反転用文字を返す
return convertKey;
} catch (IOException e) {
//反転用文字を取得できない場合、ログを出力する。
logger.info(LOG_CONVERT_KEY_READ_ERROR);
//スクリーンへメッセージを出力する。
System.out.println(CONSOLE_CONVERT_KEY_READ_ERROR);
throw e;
} finally {
//ファイルをクローズする
if (br != null) {
br.close();
}
}
}
}