【Java】 シリアル番号やパスワードの読みを振り仮名に変換するプログラムを考える

はじめに

http://blogs.yahoo.co.jp/dk521123/36538970.html
で以下のような問題があるって書いた。
~~~~~~~~~~~~
 * 以下の文字が紛らわしく間違うトラブルがあるとかないとか...

  + 数字の「0(ゼロ)」と英字の「O(オー)」
  + 数字の「1(イチ)」と英字の「l(エル)」or「I(アイ)」
  + 数字の「8(ハチ)」と英字の「B(ビー)」
~~~~~~~~~~~~

その解決策として
~~~~~~~~~~~~
 => カタカナで振り仮名振るなどの対策が必要かも...
~~~~~~~~~~~~
と書いたので、そのプログラムを書いてみる

サンプル

PasswordReader.java

import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.HashMap;

import javax.xml.bind.DatatypeConverter;

public class PasswordReader {

  public static void main(String[] args) {
    try {
      String samplePassword = createPassword();
      System.out.println("元ネタ : " + samplePassword);
      
      String reading = convertReading(samplePassword);
      System.out.println("振り仮名 : " + reading);
    } catch (NoSuchAlgorithmException ex) {
      ex.printStackTrace();
    }
  }

  private static final String DELIMITER = "・";
  private static final String NOT_SUPPORTED_CHARACTER = "??";

  private static HashMap<String, String> mapper = new HashMap<String, String>() {
    private static final long serialVersionUID = 1L;
    {
      // ここは、キーとして「対応する文字」と値として「振り仮名」を対応させる
      put("0", "ぜろ");
      put("1", "いち");
      put("2", "に");
      put("3", "さん");
      put("4", "よん");
      put("5", "ご");
      put("6", "ろく");
      put("7", "なな");
      put("8", "はち");
      put("9", "きゅー");
      put("A", "エー");
      put("B", "ビー");
      put("C", "シー");
      put("D", "ディー");
      put("E", "イー");
      put("F", "エフ");
      put("G", "ジー");
      put("H", "エッチ");
      put("I", "アイ");
      put("J", "ジェー");
      put("K", "ケー");
      put("L", "エル");
      put("M", "エム");
      put("N", "エヌ");
      put("O", "オー");
      put("P", "ピー");
      put("Q", "キュー");
      put("R", "アル");
      put("S", "エス");
      put("T", "ティー");
      put("U", "ユー");
      put("V", "ヴィ");
      put("W", "ダブリュー");
      put("X", "エックス");
      put("Y", "ワイ");
      put("Z", "ゼット");
    }
  };

  /**
   * 対象値を読みに変換する
   * 
   * @param targetValue
   *          対象値
   * @return 読み
   * @see http://blogs.yahoo.co.jp/dk521123/36538970.html
   */
  public static String convertReading(String targetValue) {
    StringBuilder returnValue = new StringBuilder();
    for (int i = 0; i < targetValue.length(); i++) {
      if (i != 0) {
        returnValue.append(DELIMITER);
      }

      String targetCharacter = String.valueOf(targetValue.charAt(i));
      if (mapper.containsKey(targetCharacter)) {
        returnValue.append(mapper.get(targetCharacter));
      } else {
        // 対応していない文字だったら「??」を表示
        returnValue.append(NOT_SUPPORTED_CHARACTER);
      }
    }

    return returnValue.toString();
  }

  // パスワード自動生成として
  // http://blogs.yahoo.co.jp/dk521123/36415526.html
  // とほぼ同じプログラムを使用(ここは、どうでもいい)
  private static int DEFAULT_PASSWORD_LENGTH = 8;
  private static String createPassword() throws NoSuchAlgorithmException {
    SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
    byte tokenBytes[] = new byte[DEFAULT_PASSWORD_LENGTH];
    random.nextBytes(tokenBytes);
    return DatatypeConverter.printHexBinary(tokenBytes).toUpperCase();
  }
}

出力結果

例1
元ネタ : 6FE57F268C28287E
振り仮名 : ろく・エフ・イー・ご・なな・エフ・に・ろく・はち・シー・に・はち・に・はち・なな・イー
例2
元ネタ : EB9AB77A93CAEBC9
振り仮名 : イー・ビー・きゅー・エー・ビー・なな・なな・エー・きゅー・さん・シー・エー・イー・ビー・シー・きゅー

関連記事

Java で、シリアル番号生成を考える

http://blogs.yahoo.co.jp/dk521123/36538970.html

セキュアなランダム文字列生成を考える

http://blogs.yahoo.co.jp/dk521123/36415526.html