C++ でパスワード生成機を作る

(1/1)
C++でパスワード生成機を作る
PHP で WinAsm を使って Windows プログラムをデザイン」で作ったパスワード生成機を C++に移植する。

パスワード文字は、英大文字、英小文字、数字、記号の 1 つまたは複数を組み合わせ、任意の長さのパスワードを生成する。生成したパスワードはクリップボードにコピーできるようにする。
(2020 年 9 月 6 日)インストーラー,ヘルプファイル,メニュー追加.

目次

サンプル・プログラム

圧縮ファイルの内容
makepassword.msiインストーラ
bin/makepassword.exe実行プログラム本体
bin/etc/help.chmヘルプ・ファイル
sour/makepassword.cppソース・プログラム
sour/resource.hリソース・ヘッダ
sour/resource.rcリソース・ファイル
sour/application.icoアプリケーション・アイコン

リソースの準備

Eclipse を起動し、新規プロジェクト makepassword を用意する。
ResEdit を起動し、resource.rc を用意する。

Eclipse に戻り、ソース・プログラム "makepassword.cpp" を追加する。
リンカー・フラグを "-mwindows -static -lstdc++ -lgcc -lwinpthread" に設定する。

使用ライブラリ

今回は、オープンソースのライブラリ Boost C++ライブラリを使用する。導入方法等については、「C++ 開発環境の準備」をご覧いただきたい。

プログラムの解説

0009: // 初期化処理 ======================================================
0010: #include <iostream>
0011: #include <stdio.h>
0012: #include <stdlib.h>
0013: #include <tchar.h>
0014: #include <time.h>
0015: #include <random>
0016: #include <sstream>
0017: #include <string>
0018: #include <windows.h>
0019: #include <commctrl.h>
0020: #include <richedit.h>
0021: #include <boost/format.hpp>
0022: #include "resource.h"
0023: 
0024: using namespace std;
0025: 
0026: #define APPNAME     "パスワード生成機"        //アプリケーション名
0027: #define APPVERSION "1.1"                    //バージョン
0028: #define APPYEAR     "2020"                    //作成年
0029: #define REFERENCE "https://www.pahoo.org/e-soul/webtech/cpp01/cpp01-05-01.shtm"  // 参考サイト
0030: 
0031: //char*バッファサイズ
0032: #define SIZE_BUFF     512
0033: 
0034: //標準フォント
0035: #define FONT_FACE     "MS UI Gothic"
0036: 
0037: //現在のインターフェイス
0038: static HINSTANCE hInst;
0039: 
0040: //親ウィンドウ
0041: static HWND hParent;
0042: 
0043: //エラー・メッセージ格納用
0044: string ErrorMessage;
0045: 
0046: //ヘルプ・ファイル
0047: #define HELPFILE ".\\etc\\help.chm"
0048: 
0049: 
0050: //パスワードに使う文字セット
0051: const string Seed[] = {
0052:     "ABCDEFGHIJKLMNOPQRSTUVWXYZ",        //英大文字
0053:     "abcdefghijklmnopqrstuvwxyz",        //英小文字
0054:     "0123456789",                        //数字
0055:     "()%$#+-*"                            //記号
0056: };
0057: 
0058: //生成するパスワードの最小桁数と最大桁数
0059: #define MIN_PASSWORD 4
0060: #define MAX_PASSWORD 20
0061: 
0062: //乱数関係
0063: std::random_device rnd;            //非決定的な乱数生成器を生成
0064: std::mt19937 mt((int)time(0)); //メルセンヌ・ツイスタの32ビット版+シード

パスワードに使う文字セットは配列 Seed に用意する。
生成するパスワードの最小桁数と最大桁数を定義する。
文字列を操作するために、char*バッファのサイズを SIZE_BUFF に定義する。

疑似乱数として C++の rand関数を使おうとしたが、偏りがあるので、random ライブラリにあるメルセンヌ・ツイスタ乱数を使うことにする。

0067: /**
0068:  * クリップボードに文字列をセット
0069:  * @param string str 文字列
0070:  * @return なし
0071: */
0072: void setClipboardData(string str) {
0073:     char buff[SIZE_BUFF];
0074:     char_traits<char>::copy(buffstr.c_str(), str.size() + 1);
0075: 
0076:     OpenClipboard(NULL);
0077:     EmptyClipboard();
0078: 
0079:     HGLOBAL hText = GlobalAlloc(GHND | GMEM_SHARESIZE_BUFF);
0080:     PTSTR pText = (PTSTR)GlobalLock(hText);
0081:     lstrcpy(pTextbuff);
0082:     GlobalUnlock(hText);
0083:     SetClipboardData(CF_TEXThText);
0084:     CloseClipboard();
0085: }

クリップボードに文字列をセットするユーザー関数 setClipboardData を用意した。Win32API を利用するもので、「PHP でクリップボードにテキスト貼り付け(Windows アプリ版)」で作ったプログラムを C++に移植した。

0031: /**
0032:  * ダイアログボックス
0033:  * @param HWND hDlg
0034:  * @paramm UINT uMsg
0035:  * @param WPARAM wParam
0036:  * @paramL PARAM lParam
0037:  * @return INT_PTR CALLBACK
0038: */
0039: INT_PTR CALLBACK DlgProc(HWND hDlgUINT uMsgWPARAM wParamLPARAM lParam) {
0040:     char buff[255];
0041: 
0042:     time_t t = time(0);                  //現在時刻
0043:     tmnow = localtime(&t);         //ローカルタイム
0044:     int year = now->tm_year + 1900;        //西暦年を取り出す
0045:     bool res = isleap(year);         //閏年かどうか判定する
0046: 
0047:     switch(uMsg) {
0048:         case WM_INITDIALOG:
0049:             snprintf(buffsizeof(buff), "%d年は 閏年%s", year, (res ? "です." : "ではありません."));
0050:             SetDlgItemText(hDlgIDC_LABELbuff);
0051:             break;
0052:         case WM_CLOSE:
0053:             EndDialog(hDlg, 0);
0054:             break;
0055:     }
0056:     return 0;
0057: }

ダイアログボックス関数にイベントが増えた。
ボタンをクリックすると、WM_COMMAND イベントが発生する。クリックされたボタンの ID で処理を場合分けする。

参考サイト

(この項おわり)
header