HexspeakGeneraterで単語からHexspeakに変換できるなら,その逆変換もあるべきじゃないかってことで,HexspeakReverseGeneratorを書いてみた.これまた動作優先で書いたので,クラス分割すらせず,全ての責務を1クラスに押し付けるという強引なコードになっちゃった.
これでマジックナンバーが探せる?
"1"は"L"と"I"に読み替えられるので,推定変換候補として2件出てくる.どちらの候補に意味があるかどうかは辞書探索などをしないと厳しいような気がするので,現時点では候補を眺めて意味を特定するのみ.でもこれで"big boobs"を発見できる.
>java jp.kakku.mainlogic.HexspeakReverseGenerator "0xB16B00B5"
- -
[0xB16B00B5] 推定変換候補=2件
- > blgboobs
- > bigboobs
- -
HexspeakReverseGenerator.java
package jp.kakku.mainlogic; import java.util.ArrayList; public class HexspeakReverseGenerator { // 推定候補リスト public static ArrayList<String> tempWordListMaster = new ArrayList<String>(); public static ArrayList<String> tempWordListCopy = new ArrayList<String>(); public static void main(String[] args) { // Hexspeakを受け取る String transBefore = args[0]; // 冒頭の'0x'を除いて,小文字に変換する String transBeforeWithoutOX = transBefore.substring(2, transBefore.length()).toLowerCase(); tempWordListMaster.add(transBeforeWithoutOX); // 10進数変換で16進数になっているか確認し,16進数でなかった場合は処理を中断する try { Long.parseLong(transBeforeWithoutOX, 16); } catch (NumberFormatException e) { System.out.println("NotHexError"); System.exit(1); } // // Hexspeakから単語の候補を推定する // // "0"の変換 tempWordListCopy = new ArrayList<String>(tempWordListMaster); tempWordListMaster = new ArrayList<String>(); for (String obj : tempWordListCopy) { replaceZero(obj); } // "5"の変換 tempWordListCopy = new ArrayList<String>(tempWordListMaster); tempWordListMaster = new ArrayList<String>(); for (String obj : tempWordListCopy) { replaceFive(obj); } // "6"の変換 tempWordListCopy = new ArrayList<String>(tempWordListMaster); tempWordListMaster = new ArrayList<String>(); for (String obj : tempWordListCopy) { replaceSix(obj); } // "8"の変換 tempWordListCopy = new ArrayList<String>(tempWordListMaster); tempWordListMaster = new ArrayList<String>(); for (String obj : tempWordListCopy) { replaceEight(obj); } // "1"の変換 tempWordListCopy = new ArrayList<String>(tempWordListMaster); tempWordListMaster = new ArrayList<String>(); for (String obj : tempWordListCopy) { replaceOne(obj); } // 変換結果を標準出力する System.out.println("------------------------------"); System.out.println("[" + transBefore + "] 推定変換候補=" + tempWordListMaster.size() + "件"); for (String word : tempWordListMaster) { System.out.println("-> " + word); } System.out.println("------------------------------"); } // "0" -> "o" static void replaceZero(String temp) { // 単一変換 tempWordListMaster.add(temp.replace("0", "o")); } // "1" -> "l" // "1" -> "i" public static void replaceOne(String temp) { // 複数候補変換 if (temp.contains("1")) { // 再帰的に変換をしていく replaceOne(temp.replaceFirst("1", "l")); replaceOne(temp.replaceFirst("1", "i")); } else { tempWordListMaster.add(temp); } } // "5" -> "S" public static void replaceFive(String temp) { // 単一変換 tempWordListMaster.add(temp.replace("5", "s")); } // "6" -> "G" public static void replaceSix(String temp) { // 単一変換 tempWordListMaster.add(temp.replace("6", "g")); } // "8" -> "at" public static void replaceEight(String temp) { // 単一変換 tempWordListMaster.add(temp.replace("8", "at")); } }