文系出身システム屋の技術日記

自分がつまづいたテクニカルなこと、役に立ったことをまとめます。

自作アプリのデバッグの過程を徒然なるままに書く② (ループ文の恐怖)

こんばんは。

一昨日、昨日、今日とデバッグの沼にはまって睡眠時間がゴリゴリ削られているにぎりめしです。

あくまで趣味でやっていることなので精神的なダメージは0なのですが、

次の日も仕事があるため、「デバッグまだ終わってないけど寝なければ・・・」

となった時の敗北感たるや!


しかも個人で開発しているアプリなので、

このくそみたいなコードを書いたのも自分、そして今デバッグをしているのも自分…!

そう思うと、過去の自分を責めたくなることもありますね。


さて、閑話休題ということで。

実はいま作っているのはお手軽にパスワードを生成するアプリ。

こいつの中にループを回す処理があるのですが、そこで無限ループが発生し、

いわゆるANR状態に陥っています。

しかも常にそうなるわけではなく、特定の条件下でのみ発生するのでタチが悪い。

どうやらループ文の条件分岐が怪しい気配なのですが…


パスワードを生成する処理の実装は以下のような感じになっています。
(※一部簡略化しています)

private String generatePassword() {

    //以下の各変数の値は実際にはユーザの入力に応じて可変
    String password = "";
    String passwordBase = "0123456789abcdefghij";  //パスワードの元になる文字列 
    int numOfPassword = 20;    //任意のパスワード長
    int passwordBaseLength = passwordBase.length(); //passwordBaseの長さ
    int prevIndex = -1;    //直前の添字
    boolean enableDoubleChar = false;    //連続文字を許可しない
    boolean enableSameChar = false;    //重複文字を許可しない


    for(int count=0;count<numOfPassword;count++) {

        Random rand = new Random();
        int index = rand.nextInt(passKeyLength -1);

        if(prevIndex != -1) {
            if (!enableDoubleChar && !enableSameChar) {
               while (index == prevIndex || password.indexOf(passwordKey.charAt(index)) != -1) {
                   index = rand.nextInt(passKeyLength - 1);
               }
            } else if (!enableDoubleChar) {
                while (prevIndex == index) {
                    index = rand.nextInt(passKeyLength - 1);
                }
            } else if (!enableSameChar) {
                while (password.indexOf(passwordKey.charAt(index)) != -1) {
                    index = rand.nextInt(passKeyLength - 1);
                }
            }
        }
        password += passwordKey.charAt(index);
        prevIndex = index;
    }
    return password;
}

上述のバグが発生する「特定の条件下」というのはnumOfPasswordとpasswordBaseの文字列長が一致するときなのですが・・・

ふむ・・・

今夜もデバッグに睡眠時間が持っていかれそうです。


ではではー。