]> vaikene.ee Git - evaf/blob - www/pswgen04.html
Fixed typo
[evaf] / www / pswgen04.html
1 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2 <html lang="et" xmlns="http://www.w3.org/1999/xhtml" xml:lang="et">
3
4 <head>
5 <meta http-equiv="CONTENT-TYPE" content="text/html; charset=utf-8" />
6 <title>eVaf Tutorial - 04 - Generator Module</title>
7 <meta name="Author" content="Enar Väikene" />
8 <meta name="description" content="eVaf Tutorial" />
9 <meta name="keywords" content="evaf c++ application development framework tutorial password generator" />
10 <link rel="StyleSheet" href="evaf.css" type="text/css" media="all" />
11 <link rel="StyleSheet" href="highlight.css" type="text/css" media="all" />
12 </head>
13
14 <body>
15
16 <h1>eVaf Tutorial</h1>
17
18 <h2>04 - Generator Module</h2>
19
20 <p>Now we are going to implement all the classes declared in the <tt>module.h</tt>. Create the <tt>module.cpp</tt> file
21 in the <tt>src/apps/PswGen/Generator</tt> directory. We obviously include the <tt>module.h</tt> header file, but also
22 the <tt>QtCore</tt> header file for any non-GUI Qt classes.</p>
23
24 <pre class="hl"><span class="hl com">/**</span>
25 <span class="hl com"> * &#64;file src/apps/PswGen/Generator/module.cpp</span>
26 <span class="hl com"> */</span>
27
28 <span class="hl ppc">#include</span> <span class="hl pps">&quot;module.h&quot;</span><span class="hl ppc"></span>
29
30 <span class="hl ppc">#include &lt;QtCore&gt;</span></pre>
31
32 <p>All the eVaf modules need to include version information. This is common for all the modules and we can simply
33 copy existing version info files from another eVaf module:</p>
34
35 <pre>evaf/src/apps/PswGen/Generator $ <code>cp ../../../plugins/SdiWindow/version.{h,rc} .</code></pre>
36
37 <p>The <tt>version.h</tt> file contains version information for the module. The <tt>version.rc</tt> is for Windows
38 builds only and embeds the same version information into the dll or exe file. Modify the copied <tt>version.h</tt>
39 file for our new module. The <tt>version.rc</tt> file uses the values from the <tt>version.h</tt> and does not
40 need to be touched.</p>
41
42 <pre class="hl"><span class="hl com">/**</span>
43 <span class="hl com"> * &#64;file src/apps/PswGen/Generator/version.h</span>
44 <span class="hl com"> */</span>
45 <span class="hl ppc">#ifndef __PSWGEN_GENERATOR_VERSION_H</span>
46 <span class="hl ppc">#define __PSWGEN_GENERATOR_VERSION_H</span>
47
48 <span class="hl ppc">#include &lt;version_rc.h&gt;</span>
49
50 <span class="hl com">/**</span>
51 <span class="hl com"> * Module/library version number in the form major,minor,release,build</span>
52 <span class="hl com"> */</span>
53 <span class="hl ppc">#define VER_FILE_VERSION 0,1,1,1</span>
54
55 <span class="hl com">/**</span>
56 <span class="hl com"> * Module/library version number in the string format (shall end with \0)</span>
57 <span class="hl com"> */</span>
58 <span class="hl ppc">#define VER_FILE_VERSION_STR</span> <span class="hl pps">&quot;0.1.1.1\0&quot;</span><span class="hl ppc"></span>
59
60 <span class="hl com">/**</span>
61 <span class="hl com"> * Module/library name (shall end with \0)</span>
62 <span class="hl com"> */</span>
63 <span class="hl ppc">#define VER_MODULE_NAME_STR</span> <span class="hl pps">&quot;PswGen\0&quot;</span><span class="hl ppc"></span>
64
65 <span class="hl com">/**</span>
66 <span class="hl com"> * Module type (see version_rc.h for all the types)</span>
67 <span class="hl com"> */</span>
68 <span class="hl ppc">#define VER_MODULE_TYPE MT_GENERIC</span>
69
70 <span class="hl com">/**</span>
71 <span class="hl com"> * Module type in the string format (see version_rc for all the types)</span>
72 <span class="hl com"> */</span>
73 <span class="hl ppc">#define VER_MODULE_TYPE_STR MT_GENERIC</span>
74
75 <span class="hl com">/**</span>
76 <span class="hl com"> * Original file name for windows (shall end with \0)</span>
77 <span class="hl com"> */</span>
78 <span class="hl ppc">#define VER_ORIGINAL_FILE_NAME_STR</span> <span class="hl pps">&quot;PswGen.dll\0&quot;</span><span class="hl ppc"></span>
79
80 <span class="hl com">/**</span>
81 <span class="hl com"> * Description of the module/library (shall end with \0)</span>
82 <span class="hl com"> */</span>
83 <span class="hl ppc">#define VER_FILE_DESCRIPTION_STR</span> <span class="hl pps">&quot;Module that generates strong passwords using MD5 hashes.\0&quot;</span><span class="hl ppc"></span>
84
85 <span class="hl ppc">#endif</span> <span class="hl slc">// version.h</span><span class="hl ppc"></span></pre>
86
87 <p>Then include the version info file in the <tt>module.cpp</tt> file and use the <tt>VER_EXPORT_VERSION_INFO()</tt> macro
88 to export version information from the module. This macro defines a public function that all the eVaf modules export and
89 is used to collect version information from them. In your modules you only need to modify the <tt>version.h</tt> file and then
90 use the <tt>VER_EXPORT_VERSION_INFO()</tt> macro once somewhere in your code.</p>
91
92 <pre class="hl"><span class="hl ppc">#include</span> <span class="hl pps">&quot;version.h&quot;</span><span class="hl ppc"></span>
93
94 <span class="hl kwd">VER_EXPORT_VERSION_INFO</span><span class="hl opt">()</span></pre>
95
96 <p>To make the <tt>Module</tt> class a proper Qt plugin, we use the <tt>Q_EXPORT_PLUGIN2</tt> macro. The name of the module is already
97 defined in the <tt>version.h</tt> header file as <tt>VER_MODULE_NAME_STR</tt>.
98
99 <pre class="hl"><span class="hl kwd">Q_EXPORT_PLUGIN2</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">,</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>Generator<span class="hl opt">::</span>Module<span class="hl opt">)</span></pre>
100
101 <p>We make our life easier with several <tt>using namespace</tt> keywords:</p>
102
103 <pre class="hl"><span class="hl kwa">using namespace</span> eVaf<span class="hl opt">;</span>
104 <span class="hl kwa">using namespace</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">;</span>
105 <span class="hl kwa">using namespace</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>Generator<span class="hl opt">;</span></pre>
106
107 <p>The Module class needs to instantiate the <tt>iGenerator</tt> interface in the constructor. We also need to set
108 the QObject's name property to the name of the plugin by combining the name of the module with the name of the class.
109 While the application would work without the name property, it makes our life much easier if the name property is set.</p>
110
111 <p>Finally, we output an info message telling that the object was created. Every eVaf module and class is expected to
112 output info messages when they are created, destroyed, initialized or destroyed.</p>
113
114 <pre class="hl">Module<span class="hl opt">::</span><span class="hl kwd">Module</span><span class="hl opt">()</span>
115 <span class="hl opt">:</span> Plugins<span class="hl opt">::</span><span class="hl kwd">iPlugin</span><span class="hl opt">()</span>
116 <span class="hl opt">{</span>
117 <span class="hl kwd">setObjectName</span><span class="hl opt">(</span><span class="hl kwd">QString</span><span class="hl opt">(</span><span class="hl str">&quot;%1.%2&quot;</span><span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>__FUNCTION__<span class="hl opt">));</span>
118
119 mGenerator <span class="hl opt">=</span> <span class="hl kwa">new</span> Internal<span class="hl opt">::</span>GeneratorImpl<span class="hl opt">;</span>
120
121 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s created&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
122 <span class="hl opt">}</span></pre>
123
124 <p>The <tt>EVAF_INFO</tt> macro comes from the <tt>Common/iLogger</tt> header file ane we need to include it:</p>
125
126 <pre class="hl"><span class="hl ppc">#include &lt;Common/iLogger&gt;</span></pre>
127
128 <p>The destructor should delete the <tt>iGenerator</tt> interface object, which we created in the constructor. The common
129 rule is that any resources allocated in the constructor shall be released in the destructor, preferrably in the opposite
130 order, ie. the first resource allocated in the constructor is released last in the destructor.</tt>
131
132 <pre class="hl">Module<span class="hl opt">::~</span><span class="hl kwd">Module</span><span class="hl opt">()</span>
133 <span class="hl opt">{</span>
134 <span class="hl kwa">delete</span> mGenerator<span class="hl opt">;</span>
135
136 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s destroyed&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
137 <span class="hl opt">}</span></pre>
138
139 <p>We also need to implement <tt>init()</tt> and <tt>done()</tt> functions, which are used to initialize and finalize modules.
140 They are similar to the constructor and destructor with two major differences:</p>
141 <ol>
142 <li>The <tt>init()</tt> function can fail and return <tt>false</tt> to indicate a failure. eVaf does not use exceptions and
143 this is the only way for a module to fail without terminating the whole application. A failed module will be disabled
144 and the rest of the application can still run if it can.</li>
145 <li>eVaf modules are loaded in two steps. At first, all the modules are created, which means that all the objects
146 are constructed. Only then will eVaf call <tt>init()</tt> functions meaning that when the <tt>init()</tt> function is
147 called, all the modules are already loaded and instantiated. Interfaces and resources from other modules that might be not
148 available when the object is created, are available when the <tt>init()</tt> function is called.</li>
149 </ol>
150
151 <p>The rule for <tt>init()</tt> and <tt>done()</tt> functions is the same than for constructors and destructors -- any resource
152 allocated in the <tt>init()</tt> function shall be released in the <tt>done()</tt> function and preferrably in the opposite
153 order.</p>
154
155 <p>This simple module needs no extra resources to be allocated and our <tt>init()</tt> and <tt>done()</tt> functions can be
156 the following:</p>
157
158 <pre class="hl"><span class="hl kwb">bool</span> Module<span class="hl opt">::</span><span class="hl kwd">init</span><span class="hl opt">(</span>QString <span class="hl kwb">const</span> <span class="hl opt">&amp;</span> args<span class="hl opt">)</span>
159 <span class="hl opt">{</span>
160 <span class="hl kwd">Q_UNUSED</span><span class="hl opt">(</span>args<span class="hl opt">);</span>
161
162 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s initialized&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
163
164 <span class="hl kwa">return true</span><span class="hl opt">;</span>
165 <span class="hl opt">}</span>
166
167 <span class="hl kwb">void</span> Module<span class="hl opt">::</span><span class="hl kwd">done</span><span class="hl opt">()</span>
168 <span class="hl opt">{</span>
169 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s finalized&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
170 <span class="hl opt">}</span></pre>
171
172 <p>We continue by implementing the <tt>iGenerator</tt> interface. There are no resources to be allocated in the constructor
173 and we just set the QObject's name property and output the info message.</p>
174
175 <p>We also register the <tt>iGenerator</tt> interface in the global registry so that other modules can query for it and
176 use our interface. This is done by using the <tt>Common::iRegistry</tt> interface, which we need to include:</p>
177
178 <pre class="hl"><span class="hl ppc">#include &lt;Common/iRegistry&gt;</span></pre>
179
180 <p>The <tt>GeneratorImpl</tt> class was declared in the <tt>eVaf::PswGen::Generator::Internal</tt> namespace, so we need
181 another <tt>using namespace</tt> keyword before the implementation of the class:</p>
182
183 <pre class="hl"><span class="hl kwa">using namespace</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>Generator<span class="hl opt">::</span>Internal<span class="hl opt">;</span>
184
185 GeneratorImpl<span class="hl opt">::</span><span class="hl kwd">GeneratorImpl</span><span class="hl opt">()</span>
186 <span class="hl opt">:</span> <span class="hl kwd">iGenerator</span><span class="hl opt">()</span>
187 <span class="hl opt">{</span>
188 <span class="hl kwd">setObjectName</span><span class="hl opt">(</span><span class="hl kwd">QString</span><span class="hl opt">(</span><span class="hl str">&quot;%1.iGenerator&quot;</span><span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">));</span>
189
190 Common<span class="hl opt">::</span>iRegistry<span class="hl opt">::</span><span class="hl kwd">instance</span><span class="hl opt">()-&gt;</span><span class="hl kwd">registerInterface</span><span class="hl opt">(</span><span class="hl str">&quot;iGenerator&quot;</span><span class="hl opt">,</span> <span class="hl kwa">this</span><span class="hl opt">);</span>
191
192 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s created&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
193 <span class="hl opt">}</span>
194
195 GeneratorImpl<span class="hl opt">::~</span><span class="hl kwd">GeneratorImpl</span><span class="hl opt">()</span>
196 <span class="hl opt">{</span>
197 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s destroyed&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
198 <span class="hl opt">}</span></pre>
199
200 <p>Finally, we write the <tt>generatePassword</tt> function that does the actual job of the module.</p>
201
202 <p>We use the MD5 cryptographic hash function to calculate a hash value over the <tt>name</tt> and <tt>masterPassword</tt> values.
203 The result, which is a binary blob, needs to be convert into something that can be used as a password and we use base 64 encoding
204 for this and cut the result to the requested length:</p>
205
206 <pre class="hl">QString GeneratorImpl<span class="hl opt">::</span><span class="hl kwd">generatePassword</span><span class="hl opt">(</span>QString <span class="hl kwb">const</span> <span class="hl opt">&amp;</span> name<span class="hl opt">,</span> QString <span class="hl kwb">const</span> <span class="hl opt">&amp;</span> masterPassword<span class="hl opt">,</span> <span class="hl kwb">int</span> length<span class="hl opt">,</span> uint flags<span class="hl opt">)</span> <span class="hl kwb">const</span>
207 <span class="hl opt">{</span>
208 <span class="hl kwd">Q_UNUSED</span><span class="hl opt">(</span>flags<span class="hl opt">);</span>
209
210 QByteArray inputString <span class="hl opt">=</span> <span class="hl kwd">QString</span><span class="hl opt">(</span><span class="hl str">&quot;%1%2&quot;</span><span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>name<span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>masterPassword<span class="hl opt">).</span><span class="hl kwd">toLatin1</span><span class="hl opt">();</span>
211 QCryptographicHash <span class="hl kwd">hash</span><span class="hl opt">(</span>QCryptographicHash<span class="hl opt">::</span>Md5<span class="hl opt">);</span>
212 hash<span class="hl opt">.</span><span class="hl kwd">addData</span><span class="hl opt">(</span>inputString<span class="hl opt">);</span>
213 QByteArray result <span class="hl opt">=</span> hash<span class="hl opt">.</span><span class="hl kwd">result</span><span class="hl opt">().</span><span class="hl kwd">toBase64</span><span class="hl opt">();</span>
214 <span class="hl kwa">if</span> <span class="hl opt">(</span>length <span class="hl opt">&gt;</span> <span class="hl num">0</span><span class="hl opt">)</span>
215 <span class="hl kwa">return</span> result<span class="hl opt">.</span><span class="hl kwd">left</span><span class="hl opt">(</span>length<span class="hl opt">);</span>
216 <span class="hl kwa">else</span>
217 <span class="hl kwa">return</span> result<span class="hl opt">;</span>
218 <span class="hl opt">}</span></pre>
219
220 <p>We also know now the maximum length of the generated password, which is 24. Go back to the <tt>module.h</tt> header file and
221 modify the <tt>GeneratorImpl::maxLength()</tt> function:</p>
222
223 <pre class="hl"><span class="hl kwc">virtual</span> <span class="hl kwb">int</span> <span class="hl kwd">maxLength</span><span class="hl opt">()</span> <span class="hl kwb">const</span> <span class="hl opt">{</span> <span class="hl kwa">return</span> <span class="hl num">24</span><span class="hl opt">; }</span></pre>
224
225 <p>Here is the final <tt>module.cpp</tt> file:</p>
226
227 <pre class="hl"><span class="hl com">/**</span>
228 <span class="hl com"> * &#64;file src/apps/PswGen/Generator/module.cpp</span>
229 <span class="hl com"> */</span>
230
231 <span class="hl ppc">#include</span> <span class="hl pps">&quot;module.h&quot;</span><span class="hl ppc"></span>
232 <span class="hl ppc">#include</span> <span class="hl pps">&quot;version.h&quot;</span><span class="hl ppc"></span>
233
234 <span class="hl ppc">#include &lt;Common/iLogger&gt;</span>
235 <span class="hl ppc">#include &lt;Common/iRegistry&gt;</span>
236
237 <span class="hl ppc">#include &lt;QtCore&gt;</span>
238
239 <span class="hl kwd">VER_EXPORT_VERSION_INFO</span><span class="hl opt">()</span>
240 <span class="hl kwd">Q_EXPORT_PLUGIN2</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">,</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>Generator<span class="hl opt">::</span>Module<span class="hl opt">)</span>
241
242 <span class="hl kwa">using namespace</span> eVaf<span class="hl opt">;</span>
243 <span class="hl kwa">using namespace</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">;</span>
244 <span class="hl kwa">using namespace</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>Generator<span class="hl opt">;</span>
245
246 Module<span class="hl opt">::</span><span class="hl kwd">Module</span><span class="hl opt">()</span>
247 <span class="hl opt">:</span> Plugins<span class="hl opt">::</span><span class="hl kwd">iPlugin</span><span class="hl opt">()</span>
248 <span class="hl opt">{</span>
249 <span class="hl kwd">setObjectName</span><span class="hl opt">(</span><span class="hl kwd">QString</span><span class="hl opt">(</span><span class="hl str">&quot;%1.%2&quot;</span><span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>__FUNCTION__<span class="hl opt">));</span>
250
251 mGenerator <span class="hl opt">=</span> <span class="hl kwa">new</span> Internal<span class="hl opt">::</span>GeneratorImpl<span class="hl opt">;</span>
252
253 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s created&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
254 <span class="hl opt">}</span>
255
256 Module<span class="hl opt">::~</span><span class="hl kwd">Module</span><span class="hl opt">()</span>
257 <span class="hl opt">{</span>
258 <span class="hl kwa">delete</span> mGenerator<span class="hl opt">;</span>
259
260 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s destroyed&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
261 <span class="hl opt">}</span>
262
263 <span class="hl kwb">bool</span> Module<span class="hl opt">::</span><span class="hl kwd">init</span><span class="hl opt">(</span>QString <span class="hl kwb">const</span> <span class="hl opt">&amp;</span> args<span class="hl opt">)</span>
264 <span class="hl opt">{</span>
265 <span class="hl kwd">Q_UNUSED</span><span class="hl opt">(</span>args<span class="hl opt">);</span>
266
267 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s initialized&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
268
269 <span class="hl kwa">return true</span><span class="hl opt">;</span>
270 <span class="hl opt">}</span>
271
272 <span class="hl kwb">void</span> Module<span class="hl opt">::</span><span class="hl kwd">done</span><span class="hl opt">()</span>
273 <span class="hl opt">{</span>
274 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s finalized&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
275 <span class="hl opt">}</span>
276
277 <span class="hl kwa">using namespace</span> eVaf<span class="hl opt">::</span>PswGen<span class="hl opt">::</span>Generator<span class="hl opt">::</span>Internal<span class="hl opt">;</span>
278
279 GeneratorImpl<span class="hl opt">::</span><span class="hl kwd">GeneratorImpl</span><span class="hl opt">()</span>
280 <span class="hl opt">:</span> <span class="hl kwd">iGenerator</span><span class="hl opt">()</span>
281 <span class="hl opt">{</span>
282 <span class="hl kwd">setObjectName</span><span class="hl opt">(</span><span class="hl kwd">QString</span><span class="hl opt">(</span><span class="hl str">&quot;%1.iGenerator&quot;</span><span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>VER_MODULE_NAME_STR<span class="hl opt">));</span>
283
284 Common<span class="hl opt">::</span>iRegistry<span class="hl opt">::</span><span class="hl kwd">instance</span><span class="hl opt">()-&gt;</span><span class="hl kwd">registerInterface</span><span class="hl opt">(</span><span class="hl str">&quot;iGenerator&quot;</span><span class="hl opt">,</span> <span class="hl kwa">this</span><span class="hl opt">);</span>
285
286 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s created&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
287 <span class="hl opt">}</span>
288
289 GeneratorImpl<span class="hl opt">::~</span><span class="hl kwd">GeneratorImpl</span><span class="hl opt">()</span>
290 <span class="hl opt">{</span>
291 <span class="hl kwd">EVAF_INFO</span><span class="hl opt">(</span><span class="hl str">&quot;%s destroyed&quot;</span><span class="hl opt">,</span> <span class="hl kwd">qPrintable</span><span class="hl opt">(</span><span class="hl kwd">objectName</span><span class="hl opt">()));</span>
292 <span class="hl opt">}</span>
293
294 QString GeneratorImpl<span class="hl opt">::</span><span class="hl kwd">generatePassword</span><span class="hl opt">(</span>QString <span class="hl kwb">const</span> <span class="hl opt">&amp;</span> name<span class="hl opt">,</span> QString <span class="hl kwb">const</span> <span class="hl opt">&amp;</span> masterPassword<span class="hl opt">,</span> <span class="hl kwb">int</span> length<span class="hl opt">,</span> uint flags<span class="hl opt">)</span> <span class="hl kwb">const</span>
295 <span class="hl opt">{</span>
296 <span class="hl kwd">Q_UNUSED</span><span class="hl opt">(</span>flags<span class="hl opt">);</span>
297
298 QByteArray inputString <span class="hl opt">=</span> <span class="hl kwd">QString</span><span class="hl opt">(</span><span class="hl str">&quot;%1%2&quot;</span><span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>name<span class="hl opt">).</span><span class="hl kwd">arg</span><span class="hl opt">(</span>masterPassword<span class="hl opt">).</span><span class="hl kwd">toLatin1</span><span class="hl opt">();</span>
299 QCryptographicHash <span class="hl kwd">hash</span><span class="hl opt">(</span>QCryptographicHash<span class="hl opt">::</span>Md5<span class="hl opt">);</span>
300 hash<span class="hl opt">.</span><span class="hl kwd">addData</span><span class="hl opt">(</span>inputString<span class="hl opt">);</span>
301 QByteArray result <span class="hl opt">=</span> hash<span class="hl opt">.</span><span class="hl kwd">result</span><span class="hl opt">().</span><span class="hl kwd">toBase64</span><span class="hl opt">();</span>
302 <span class="hl kwa">if</span> <span class="hl opt">(</span>length <span class="hl opt">&gt;</span> <span class="hl num">0</span><span class="hl opt">)</span>
303 <span class="hl kwa">return</span> result<span class="hl opt">.</span><span class="hl kwd">left</span><span class="hl opt">(</span>length<span class="hl opt">);</span>
304 <span class="hl kwa">else</span>
305 <span class="hl kwa">return</span> result<span class="hl opt">;</span>
306 <span class="hl opt">}</span></pre>
307
308 <p>Next -- <a href="pswgen05.html">05 - Building Generator Module</a>.</p>
309
310 </body>
311 </html>