FLYING

〈全日本・紀文豆乳飲料シリーズ「麦芽コーヒー」の500ミリリットルパックを扱う小売店が少ないことに遺憾の意を表明する会〉活動記録

パスワード入力を実装するのはさりげなく面倒

ユーザ認証とかでよくある、パスワードが「*」で表示されるアレを作りたい話。

簡単にできるかと思いきや、これが結構面倒だった。それというのもgetch()って関数がBackSpace, Delete, Functionキー等々、パスワード入力には必要のない文字までご丁寧に返してくれるからで、パスワード入力を実現するためにはそういう不要な文字を除外する処理を書かなければならなかった。

という訳でC言語のコード。

// パスワード入力
// 入力文字は'*'で表示される
void get_pass(char *pass, int len)
{
	int i = 0, c;
	
	while ((c = getch()) != '\n' && c != '\r') {
		// BackSpace
		if (c == '\b') {
			if (i > 0) {
				printf("\b \b");
				i--;
			}
		// Tab, Esc
		} else if (c == '\t' || c == 0x1b) {
			;
		// 制御文字, Shift-JIS
		} else if (c < 0x20 || c > 0x7e) {
			getch();
		// ASCII
		} else if (i < len) {
			putchar('*');
			pass[i++] = c;
		}
	}
	
	pass[i] = '\0';
	putchar('\n');
}

引数には入力されたパスワードを格納する配列passと、最大文字数lenを指定する(終端文字は含まない)。

AsciiコードやShift-JISについてはこのページの説明を参考にした。

BackSpaceを入力したときの処理は、カーソル変数をデクリメントして、"\b \b"という文字列を表示させることで対応した。すなわち、一文字バックして、スペースで画面バッファに残っている文字を消去。さらに一文字バックさせて、最終的には直前の文字を消したように見える、と。それ以外の制御文字・漢字は華麗にスルーする仕様。

言うまでもなくWindows環境依存の話ですた。