Commits

chai2010 committed bb23c9f

pwdgen 1.2.2

1. C++重新实现
2. 调整命令行参数
3. go版本迁移到src/golang
4. 算法和之前版本保存兼容

Comments (0)

Files changed (150)

Makefile

-# Copyright 2009 <chaishushan@gmail.com>. All rights reserved.
-# Use of this source code is governed by a BSD-style
-# license that can be found in the LICENSE file.
-
-include $(GOROOT)/src/Make.inc
-
-TARG=pwdgen
-GOFILES=\
-	main.go\
-
-include $(GOROOT)/src/Make.cmd

check/config_111.csv

-"site0-0","id0","Vo5plouo2VwWR5FU","http://www.site0.com/",""
-"site0-1","id1","FisZVis52isT8y4d","http://www.site0.com/",""
-"site0-2","id3","EjxbAcmpsHXW5E34","http://www.site0.com/",""
-"site1-0","id0","MPGK9uZIbwqw","http://www.site1.com/",""
-"site1-1","id1","isK6ii0QsCcA","http://www.site1.com/",""
-"site2","id0","pCI2ii74","http://www.site2.com/",""
-"site3","id0","hDFNiikQ","http://www.site3.com/",""
-"site4","id0","0s1n4w2U","http://www.site4.com/",""
-"site5","id0","gsrSj4g5","http://www.site5.com/",""
-"site6","id0","2PTTRtyi","http://www.site6.com/",""
-"site7","id0","ADpG0oYd","http://www.site7.com/",""
-"site8","id0","fOZaw2NV","http://www.site8.com/",""
-"site9","id0","6s9HICPA","http://www.site9.com/",""
+"site0-0","id0","Vo5plouo2VwWR5FU","http://www.site0.com/",""
+"site0-1","id1","FisZVis52isT8y4d","http://www.site0.com/",""
+"site0-2","id3","EjxbAcmpsHXW5E34","http://www.site0.com/",""
+"site1-0","id0","MPGK9uZIbwqw","http://www.site1.com/",""
+"site1-1","id1","isK6ii0QsCcA","http://www.site1.com/",""
+"site2","id0","pCI2ii74","http://www.site2.com/",""
+"site3","id0","hDFNiikQ","http://www.site3.com/",""
+"site4","id0","0s1n4w2U","http://www.site4.com/",""
+"site5","id0","gsrSj4g5","http://www.site5.com/",""
+"site6","id0","2PTTRtyi","http://www.site6.com/",""
+"site7","id0","ADpG0oYd","http://www.site7.com/",""
+"site8","id0","fOZaw2NV","http://www.site8.com/",""
+"site9","id0","6s9HICPA","http://www.site9.com/",""

check/config_111.txt

-http://www.site0.com/
-  id: id0
-  pd: Vo5plouo2VwWR5FU
-
-http://www.site0.com/
-  id: id1
-  pd: FisZVis52isT8y4d
-
-http://www.site0.com/
-  id: id3
-  pd: EjxbAcmpsHXW5E34
-
-http://www.site1.com/
-  id: id0
-  pd: MPGK9uZIbwqw
-
-http://www.site1.com/
-  id: id1
-  pd: isK6ii0QsCcA
-
-http://www.site2.com/
-  id: id0
-  pd: pCI2ii74
-
-http://www.site3.com/
-  id: id0
-  pd: hDFNiikQ
-
-http://www.site4.com/
-  id: id0
-  pd: 0s1n4w2U
-
-http://www.site5.com/
-  id: id0
-  pd: gsrSj4g5
-
-http://www.site6.com/
-  id: id0
-  pd: 2PTTRtyi
-
-http://www.site7.com/
-  id: id0
-  pd: ADpG0oYd
-
-http://www.site8.com/
-  id: id0
-  pd: fOZaw2NV
-
-http://www.site9.com/
-  id: id0
-  pd: 6s9HICPA
-
+Name    : site0-0
+Web Site: http://www.site0.com/
+ID      : id0
+Password: Vo5plouo2VwWR5FU
+Comments: 
+
+Name    : site0-1
+Web Site: http://www.site0.com/
+ID      : id1
+Password: FisZVis52isT8y4d
+Comments: 
+
+Name    : site0-2
+Web Site: http://www.site0.com/
+ID      : id3
+Password: EjxbAcmpsHXW5E34
+Comments: 
+
+Name    : site1-0
+Web Site: http://www.site1.com/
+ID      : id0
+Password: MPGK9uZIbwqw
+Comments: 
+
+Name    : site1-1
+Web Site: http://www.site1.com/
+ID      : id1
+Password: isK6ii0QsCcA
+Comments: 
+
+Name    : site2
+Web Site: http://www.site2.com/
+ID      : id0
+Password: pCI2ii74
+Comments: 
+
+Name    : site3
+Web Site: http://www.site3.com/
+ID      : id0
+Password: hDFNiikQ
+Comments: 
+
+Name    : site4
+Web Site: http://www.site4.com/
+ID      : id0
+Password: 0s1n4w2U
+Comments: 
+
+Name    : site5
+Web Site: http://www.site5.com/
+ID      : id0
+Password: gsrSj4g5
+Comments: 
+
+Name    : site6
+Web Site: http://www.site6.com/
+ID      : id0
+Password: 2PTTRtyi
+Comments: 
+
+Name    : site7
+Web Site: http://www.site7.com/
+ID      : id0
+Password: ADpG0oYd
+Comments: 
+
+Name    : site8
+Web Site: http://www.site8.com/
+ID      : id0
+Password: fOZaw2NV
+Comments: 
+
+Name    : site9
+Web Site: http://www.site9.com/
+ID      : id0
+Password: 6s9HICPA
+Comments: 
+

check/config_abc.csv

-"site0-0","id0","gzESRcILWbDXJBmM","http://www.site0.com/",""
-"site0-1","id1","6Nmoo07MNR2Txp47","http://www.site0.com/",""
-"site0-2","id3","3WsxRS93AUWavXPi","http://www.site0.com/",""
-"site1-0","id0","dQcVNqO3V2KJ","http://www.site1.com/",""
-"site1-1","id1","2lU9pHLc3vCN","http://www.site1.com/",""
-"site2","id0","dHisobVu","http://www.site2.com/",""
-"site3","id0","NS87VKtR","http://www.site3.com/",""
-"site4","id0","istg9VUe","http://www.site4.com/",""
-"site5","id0","PxxSzrQK","http://www.site5.com/",""
-"site6","id0","okqKGUuI","http://www.site6.com/",""
-"site7","id0","fbDPn8tq","http://www.site7.com/",""
-"site8","id0","9dfbmAJp","http://www.site8.com/",""
-"site9","id0","qaD6K59n","http://www.site9.com/",""
+"site0-0","id0","gzESRcILWbDXJBmM","http://www.site0.com/",""
+"site0-1","id1","6Nmoo07MNR2Txp47","http://www.site0.com/",""
+"site0-2","id3","3WsxRS93AUWavXPi","http://www.site0.com/",""
+"site1-0","id0","dQcVNqO3V2KJ","http://www.site1.com/",""
+"site1-1","id1","2lU9pHLc3vCN","http://www.site1.com/",""
+"site2","id0","dHisobVu","http://www.site2.com/",""
+"site3","id0","NS87VKtR","http://www.site3.com/",""
+"site4","id0","istg9VUe","http://www.site4.com/",""
+"site5","id0","PxxSzrQK","http://www.site5.com/",""
+"site6","id0","okqKGUuI","http://www.site6.com/",""
+"site7","id0","fbDPn8tq","http://www.site7.com/",""
+"site8","id0","9dfbmAJp","http://www.site8.com/",""
+"site9","id0","qaD6K59n","http://www.site9.com/",""

check/config_abc.txt

-http://www.site0.com/
-  id: id0
-  pd: gzESRcILWbDXJBmM
-
-http://www.site0.com/
-  id: id1
-  pd: 6Nmoo07MNR2Txp47
-
-http://www.site0.com/
-  id: id3
-  pd: 3WsxRS93AUWavXPi
-
-http://www.site1.com/
-  id: id0
-  pd: dQcVNqO3V2KJ
-
-http://www.site1.com/
-  id: id1
-  pd: 2lU9pHLc3vCN
-
-http://www.site2.com/
-  id: id0
-  pd: dHisobVu
-
-http://www.site3.com/
-  id: id0
-  pd: NS87VKtR
-
-http://www.site4.com/
-  id: id0
-  pd: istg9VUe
-
-http://www.site5.com/
-  id: id0
-  pd: PxxSzrQK
-
-http://www.site6.com/
-  id: id0
-  pd: okqKGUuI
-
-http://www.site7.com/
-  id: id0
-  pd: fbDPn8tq
-
-http://www.site8.com/
-  id: id0
-  pd: 9dfbmAJp
-
-http://www.site9.com/
-  id: id0
-  pd: qaD6K59n
-
+Name    : site0-0
+Web Site: http://www.site0.com/
+ID      : id0
+Password: gzESRcILWbDXJBmM
+Comments: 
+
+Name    : site0-1
+Web Site: http://www.site0.com/
+ID      : id1
+Password: 6Nmoo07MNR2Txp47
+Comments: 
+
+Name    : site0-2
+Web Site: http://www.site0.com/
+ID      : id3
+Password: 3WsxRS93AUWavXPi
+Comments: 
+
+Name    : site1-0
+Web Site: http://www.site1.com/
+ID      : id0
+Password: dQcVNqO3V2KJ
+Comments: 
+
+Name    : site1-1
+Web Site: http://www.site1.com/
+ID      : id1
+Password: 2lU9pHLc3vCN
+Comments: 
+
+Name    : site2
+Web Site: http://www.site2.com/
+ID      : id0
+Password: dHisobVu
+Comments: 
+
+Name    : site3
+Web Site: http://www.site3.com/
+ID      : id0
+Password: NS87VKtR
+Comments: 
+
+Name    : site4
+Web Site: http://www.site4.com/
+ID      : id0
+Password: istg9VUe
+Comments: 
+
+Name    : site5
+Web Site: http://www.site5.com/
+ID      : id0
+Password: PxxSzrQK
+Comments: 
+
+Name    : site6
+Web Site: http://www.site6.com/
+ID      : id0
+Password: okqKGUuI
+Comments: 
+
+Name    : site7
+Web Site: http://www.site7.com/
+ID      : id0
+Password: fbDPn8tq
+Comments: 
+
+Name    : site8
+Web Site: http://www.site8.com/
+ID      : id0
+Password: 9dfbmAJp
+Comments: 
+
+Name    : site9
+Web Site: http://www.site9.com/
+ID      : id0
+Password: qaD6K59n
+Comments: 
+

check/update.bat

-..\pwdgen.exe -f ..\config.xml -o config_111.txt -p 111 *all
-..\pwdgen.exe -f ..\config.xml -o config_111.csv -p 111 *all
-..\pwdgen.exe -f ..\config.xml -o config_abc.txt -p abc *all
-..\pwdgen.exe -f ..\config.xml -o config_abc.csv -p abc *all
 <?xml version="1.0" encoding="utf-8" ?>
+<!--
+// Copyright 2011 <chaishushan@gmail.com>. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
 
+// pwdgen config file.
+// https://bitbucket.org/chai2010/pwdgen/
+-->
 <config>
     <!-- global salt -->
     <salt>fuckcsdn</salt>
 
 pre{
 	border-left: 2px solid #AEBDCC;
-	background-color: #323232;
-	color:#9AEF3F;
+	
+	/*background-color: #323232;
+	color:#9AEF3F;*/
+	color:#5A695F;
+	
 	padding: 1em;
 	font-family: "Courier New",Georgia,helvetica, sans-serif;  
 	white-space: pre;
 <DIV CLASS="header" ID="header">
 <H1>PwdGen文档</H1>
 <H2>ChaiShushan &lt;chaishushan{AT}gmail.com&gt;</H2>
-<H3>2012-01-19</H3>
+<H3>2012-02-01</H3>
 </DIV>
 
 <DIV CLASS="toc" ID="toc">
   <OL>
   <LI><A HREF="#toc1">简介</A>
   <LI><A HREF="#toc2">算法</A>
-  <LI><A HREF="#toc3">安装</A>
-  <LI><A HREF="#toc4">参考</A>
+  <LI><A HREF="#toc3">参考</A>
   </OL>
 
 </DIV>
 <CODE>PwdGen</CODE>为一个随机密码生成工具, 生成密码由大小写字母和数字组成.
 </P>
 <P>
-基本用法: <CODE>$ pwdgen site_name</CODE>.
-</P>
-<P>
-其中<CODE>site_name</CODE>为要生成的网站名(参考配置文件). 如果为<CODE>*all</CODE>则表示生成全部密码. 例如:
+常见用法:
 </P>
 <PRE>
-$ pwdgen *all
+  $ pwdgen --site_id=id0
+  $ pwdgen --site_id=id0 --encrypt_key=???
+  
+  $ pwdgen --site_id=id0 --site_salt=site0
+  $ pwdgen --site_id=id0 --site_salt=site0 --encrypt_salt=fuckcsdn
+  
+  $ pwdgen --config=config.xml
+  $ pwdgen --config=config.xml --output=pwd.txt
+  $ pwdgen --config=config.xml --output=pwd.csv
+  $ pwdgen --config=config.xml --output=pwd.txt --encrypt_key=???
+  $ pwdgen --config=config.xml --output=pwd.csv --encrypt_key=???
 </PRE>
 <P></P>
 <P>
-默认的配置文件为<CODE>./config.xml</CODE>. 通过<CODE>-f</CODE>选项可以指定配置文件. 例如:
+查看帮助:
 </P>
 <PRE>
-$ pwdgen -f config_xxx.xml *all
+  $ pwdgen -help
 </PRE>
 <P></P>
 <P>
-通过<CODE>-o</CODE>选项可以指定到输出文件. 例如:
-</P>
-<PRE>
-$ pwdgen -f config_xxx.xml -o out.txt *all
-</PRE>
-<P></P>
-<P>
-通过<CODE>-p</CODE>选项可以指定主管理密码(如果不指定, 回车后会提示输入):
-</P>
-<PRE>
-$ pwdgen -f config_xxx.xml -o out_abc.txt -p abc *all
-</PRE>
-<P></P>
-<P>
-如果需要用<A HREF="http://keepass.info/">KeePass</A>管理生成的密码, 可以输出csv格式(然后导入<A HREF="http://keepass.info/">KeePass</A>):
-</P>
-<PRE>
-$ pwdgen -f config_xxx.xml -o out_abc.csv -p abc *all
-</PRE>
-<P></P>
-<P>
-<B>注意:</B>
+<B>注:</B>
 </P>
 <UL>
+<LI>如果输出csv格式, 可以直接导入<A HREF="http://keepass.info/">KeePass</A>管理.
 <LI>在Linux下, 如果命令行输入的密码中有特殊字符, 需要用<CODE>"\"</CODE>转义.
-<LI>在Linux下, <CODE>"-p"</CODE>指定的密码会被记录在命令行历史中, 可能造成密码泄露.
+<LI>在Linux下, <CODE>"-encrypt_key"</CODE>指定的密码会被记录在命令行历史中, 可能造成密码泄露.
 </UL>
 
 <A NAME="toc2"></A>
 <H1>2. 算法</H1>
 <P>
-<CODE>PwdGen</CODE>采用类似以下算法为各个网站生成独立的随机密码:
+<CODE>PwdGen</CODE>采用以下算法为各个网站生成独立的随机密码:
 </P>
 <PRE>
-  base62(base64(sha(md5(pwd+pwd_salt)+site_id+site_salt)))[0:len]
+  base62(base64(sha512(hexstr(md5(encrypt_key+encrypt_salt))+site_id+site_salt)))[0:len]
   
   // base64 -&gt; base62
   //  'i'   -&gt;  "ii"
 <P>
 其中<CODE>pwd</CODE>是用户输入的口令, <CODE>Base62</CODE>是为了去掉特殊字符.
 </P>
-<P>
-用户可以根据自己需要适当调整密码算法.
-</P>
 <A NAME="toc3"></A>
-<H1>3. 安装</H1>
-<OL>
-<LI>安装<CODE>Go</CODE>语言的 <A HREF="http://weekly.golang.org/">weekly</A> 版本
-<LI>下载 <CODE>pwdgen</CODE> 代码
-<LI>进入 <CODE>pwdgen</CODE> 目录, 执行 <CODE>make</CODE> 命令
-</OL>
-
-<A NAME="toc4"></A>
-<H1>4. 参考</H1>
+<H1>3. 参考</H1>
 <UL>
 <LI><A HREF="https://bitbucket.org/chai2010/pwdgen/">https://bitbucket.org/chai2010/pwdgen/</A>
 <LI><A HREF="http://zh.wikipedia.org/wiki/MD5">http://zh.wikipedia.org/wiki/MD5</A>
 <LI><A HREF="http://zh.wikipedia.org/wiki/SHA%E5%AE%B6%E6%97%8F">http://zh.wikipedia.org/wiki/SHA</A>
 <LI><A HREF="http://zh.wikipedia.org/wiki/Base64">http://zh.wikipedia.org/wiki/Base64</A>
 <LI><A HREF="http://keepass.info/">http://keepass.info/</A>
-<LI><A HREF="http://golang.org/">http://golang.org/</A>
 </UL>
 
 <HR NOSHADE SIZE=1>
 
 %!target  : html
 %!options : --encoding UTF-8
-%!style   : ./styles/zqliteash.css
+%!style   : ./styles/zqliteash_fork.css
 %!options : --css-inside --css-sugar
 %!options : --toc --toc-level 2 --enum-title
 
 
 ``PwdGen``为一个随机密码生成工具, 生成密码由大小写字母和数字组成.
 
-基本用法: ``$ pwdgen site_name``.
-
-其中``site_name``为要生成的网站名(参考配置文件). 如果为``*all``则表示生成全部密码. 例如:
-
+常见用法:
 ```
-$ pwdgen *all
+  $ pwdgen --site_id=id0
+  $ pwdgen --site_id=id0 --encrypt_key=???
+  
+  $ pwdgen --site_id=id0 --site_salt=site0
+  $ pwdgen --site_id=id0 --site_salt=site0 --encrypt_salt=fuckcsdn
+  
+  $ pwdgen --config=config.xml
+  $ pwdgen --config=config.xml --output=pwd.txt
+  $ pwdgen --config=config.xml --output=pwd.csv
+  $ pwdgen --config=config.xml --output=pwd.txt --encrypt_key=???
+  $ pwdgen --config=config.xml --output=pwd.csv --encrypt_key=???
 ```
 
-默认的配置文件为``./config.xml``. 通过``-f``选项可以指定配置文件. 例如:
-
+查看帮助:
 ```
-$ pwdgen -f config_xxx.xml *all
+  $ pwdgen -help
 ```
 
-通过``-o``选项可以指定到输出文件. 例如:
-
-```
-$ pwdgen -f config_xxx.xml -o out.txt *all
-```
-
-通过``-p``选项可以指定主管理密码(如果不指定, 回车后会提示输入):
-
-```
-$ pwdgen -f config_xxx.xml -o out_abc.txt -p abc *all
-```
-
-如果需要用[KeePass http://keepass.info/]管理生成的密码, 可以输出csv格式(然后导入[KeePass http://keepass.info/]):
-
-```
-$ pwdgen -f config_xxx.xml -o out_abc.csv -p abc *all
-```
-
-**注意:**
+**注:**
+- 如果输出csv格式, 可以直接导入[KeePass http://keepass.info/]管理.
 - 在Linux下, 如果命令行输入的密码中有特殊字符, 需要用``"\"``转义.
-- 在Linux下, ``"-p"``指定的密码会被记录在命令行历史中, 可能造成密码泄露.
+- 在Linux下, ``"-encrypt_key"``指定的密码会被记录在命令行历史中, 可能造成密码泄露.
 
 
 = 算法 =
 
-``PwdGen``采用类似以下算法为各个网站生成独立的随机密码:
+``PwdGen``采用以下算法为各个网站生成独立的随机密码:
 
 ```
-  base62(base64(sha(md5(pwd+pwd_salt)+site_id+site_salt)))[0:len]
+  base62(base64(sha512(hexstr(md5(encrypt_key+encrypt_salt))+site_id+site_salt)))[0:len]
   
   // base64 -> base62
   //  'i'   ->  "ii"
 
 其中``pwd``是用户输入的口令, ``Base62``是为了去掉特殊字符.
 
-用户可以根据自己需要适当调整密码算法.
-
-= 安装 =
-
-+ 安装``Go``语言的 [weekly http://weekly.golang.org/] 版本
-+ 下载 ``pwdgen`` 代码
-+ 进入 ``pwdgen`` 目录, 执行 ``make`` 命令
-
 
 = 参考 =
 
 - [http://zh.wikipedia.org/wiki/SHA http://zh.wikipedia.org/wiki/SHA%E5%AE%B6%E6%97%8F]
 - http://zh.wikipedia.org/wiki/Base64
 - http://keepass.info/
-- http://golang.org/
 
 
 ------------------------------

doc/styles/zqliteash_fork.css

+/* t2t --css-sugar support css
+version:
+	v0.9 090430;fixed IE bad toc link color
+	v0.8 070613;zoomq clean base gary,and support anchor ed Title
+	v0.7 2004;zoomq creat base deviantart.com
+*/
+body {
+	background-color : #fdfdfd;
+	font-family: Tahoma,SimSun,arial, helvetica, sans-serif; 
+	font-size: 92%;
+	/* line-height: 120%; */
+	margin: 0px;
+	padding: 0px;
+	color:#494D4A;
+}
+SUP,SUB{
+	font-size:11px;
+}
+a {
+	color: #3B4A4A;
+	text-decoration:underline; 
+}
+a:hover {color: #930;
+	text-decoration: none; 
+}
+a:visited {color: #45544A;
+	}
+img {border: none;}
+/*"
+"font-family: courier, monospace;
+*/
+
+pre{
+	border-left: 2px solid #AEBDCC;
+	
+	/*background-color: #323232;
+	color:#9AEF3F;*/
+	color:#5A695F;
+	
+	padding: 1em;
+	font-family: "Courier New",Georgia,helvetica, sans-serif;  
+	white-space: pre;
+	/*" begin css 3 or browser specific rules - do not remove!
+	see: http://forums.techguy.org/archive/index.php/t-249849.html */
+	white-space: pre-wrap;
+	word-wrap: break-word;
+	white-space: -moz-pre-wrap;
+	white-space: -pre-wrap;
+	white-space: -o-pre-wrap;
+	/* end css 3 or browser specific rules */
+}
+UL,OL{
+	margin: 0em 0 0 .5em;
+	padding: 0 .25em 0em 1em;
+}
+/*定义声明组*/
+DL,DT{
+	margin: .25em 0 0 .25em;
+	padding: 0em 0em 0em .25em;
+}
+DT{
+	font-weight:bold;
+	font-size:105%;
+}
+DD{
+	margin: .25em 0 0 .5em;
+	padding: 0 .25em .25em 1em;
+}
+ul.plain {
+	list-style-type: none;
+	margin-left: 5px;
+	padding-left: 5px;
+}
+H1,H2,H3,H4,H5,H6{
+	font-family: Verdana, arial, helvetica, sans-serif; 
+	text-align: left;
+	color:#5A695F;
+	margin-left : .5em;  
+	padding : 4px;
+	line-height: 1.2em;
+}
+H1 { 
+	background-color :transparent;
+	border-left : 5px solid #404E4E ;
+	border-bottom : 1px dashed  #A9B3A9 ;
+	font-size: 1.5em;
+}
+h2 { 
+	border-left : 10px solid #526157 ;
+	border-bottom : 1px dashed  #A9B3A9 ;
+	font-size: 1.4em;
+}
+h3 {
+	border-left : 15px solid #738278 ;
+	border-bottom : 1px dashed  #A9B3A9 ;
+	font-size: 1.3em;
+}
+
+h4 {
+	border-left : 20px solid #88938D ;
+	border-bottom : 1px dashed  #A9B3A9 ;
+	font-size: 1.2em;
+}
+h5{
+	border-left : 25px solid #B2B8B2 ;
+	border-bottom : 1px dashed  #A9B3A9 ;
+	font-size: 1.1em;
+}
+h6{
+	border-left : 30px solid #C4C8C4 ;
+	border-bottom : 1px dashed  #A9B3A9 ;
+	font-size: 1em;
+}
+
+H1 A{text-decoration:none;}
+H1 A:hover{text-decoration:overline;}
+
+H2 A{text-decoration:none;}
+H2 A:hover{text-decoration:overline;}
+
+H3 A{text-decoration:none;}
+H3 A:hover{text-decoration:overline;}
+
+H4 A{text-decoration:none;}
+H4 A:hover{text-decoration:overline;}
+
+H5 A{text-decoration:none;}
+H5 A:hover{text-decoration:overline;}
+
+/*padding:5px 15px 10px 15px;  */
+#banner {
+	font-family: "Courier New",Georgia,Verdana, arial, helvetica, sans-serif;
+	color:#CED8CE;
+	background:#25342A;
+	padding-left: 10px;
+	letter-spacing: .2em;
+	font-size:24px;
+	font-weight:bold ;
+	border-top:4px solid #738278;
+	border-bottom: 0px solid  #4A584A;
+}
+#banner A{
+	color:#E0FFB8;
+	text-decoration:none;
+}
+#banner A:hover{
+	color:#DAF4DA;
+	text-decoration:overline ;
+}
+#banner SUP,SUB{
+	font-size:12px;
+	color:#DAE4DA;
+}
+#banner P#main{
+	margin: 4px;
+	padding: 4px;
+}
+#banner P#sub{
+	font-size:12px;letter-spacing: 5px;
+	margin: 4px;
+	padding: 4px 4px 10px 4px;
+}
+#banner DIV#recent {
+	border : 0px dotted #930;
+	color:#DAE4DA;
+	font-family: Georgia,arial, helvetica,sans-serif;
+	position : absolute ;
+	top: 2em;
+	left: 39%;
+	font-size:16px;
+	letter-spacing: 2px;
+}
+/*text-transform:uppercase;*/
+#content { 
+	width: 69%;
+	position: absolute;	
+	background-color: transparence;
+	border-right: 0px dotted #4A584A;
+	margin: 0px;
+	padding: 10px 5px 10px 10px;
+}
+/*<h2>Mon, 23 Jan 2006</h2>*/
+h2.blosxomDate{
+	font-family: Georgia,Verdana, arial, helvetica, sans-serif;
+	text-align: right;
+	border:0px solid #2B3A3A;
+	margin: 0px 5px 5px 0px;
+	padding: 0px 15px 0px 0px;
+	border-bottom: 1px solid #2B3A3A;
+}
+H3#blosxomTitle {
+	font-size: 90%;
+	border-left:4px solid #88938D;
+	border-bottom : 0px dashed  #A9B3A9 ;
+	background-color: #546359;
+	color:#A7AFA7;
+	padding: 4px;
+	margin: 5px 0px 0px 0px;
+	font-weight:normal;
+}
+
+H3#blosxomTitle a { 
+	color: #DDDDD0;
+}
+
+.blosxomStory{
+	padding: 4px; 
+	font-size: 92%;   
+	border-left:2px solid #88938D;
+	background-color: #ECEEEC;
+}
+
+.blosxomStory a { 
+	color:#835959;
+}
+
+/*
+"font-family: "Courier New",Georgia,helvetica, sans-serif; 
+*/
+.blosxomStoryLinks{
+	font-size:90%;
+	padding: 2px;
+	margin: 0px;
+	border:0px dotted #2B3A3A;
+	background-color: #546359;
+	color:#A7AFA7;
+}
+.blosxomStoryLinks a {
+	color: #DDDDD0;
+	text-decoration:none; 
+}
+.blosxomStoryLinks a:hover {
+	color: #DDDDD0;
+	text-decoration: underline; 
+}
+.blosxomStoryLinks a:visited {
+	color: #BAC4BB;
+}
+/*"margin: 1px 0px 2px 0px  */
+div.body {
+	margin: 0px 10px 0px 10px;
+}
+div#header {
+	font-family: Verdana, Arial, Helvetica, Sans-Serif;
+	border-bottom: 0px dotted black;
+	margin: 0px;
+	padding: 0px;
+	background-color :#454545;
+}
+/*文章大标*/
+div#header H1{
+	float: left;
+	margin: 5px 5px 10px 15px;
+	padding: 5px;
+	font-size: 200%;
+	font-weight : normal;
+	color:#DAE4DA;
+	border:0px;
+}
+/*文章副标*/
+div#header H2 {
+	text-align: right;
+	margin: 0em;
+	padding: .5em .5em 0em 0em;
+	font-size: 130%;
+	font-weight : normal;
+	border:0px;
+	color:#DAE4DA;
+	border-right : 4px solid #A7AFA7;
+}
+/*文章说明*/
+div#header H3{
+	text-align: right;
+	margin: 0em;
+	padding: 0em .5em 0em 0em;
+	font-size: 13px;
+	font-weight : normal;
+	border:0px;
+	color:#D2D8D2;
+	border-bottom : 2px solid #A7AFA7;
+	border-right :  4px solid #A7AFA7;
+}
+
+div.toc {
+	float: right;
+	background-color :#454545;
+	color:#BAC4BA;
+	border-bottom : 4px solid #A7AFA7;
+	border-left :   2px solid #A7AFA7;
+	border-right :   4px solid #A7AFA7;
+	padding: .5em 0em .5em .5em;
+	margin: -2px 0px 0px 0px;
+}
+div.toc ul {
+	padding-left: .75em;
+}
+div.toc li {
+	font-size: 12px;
+}
+div.toc a {
+	text-decoration: none;
+	color:#9DAFA3;
+}
+div.toc a:hover {
+	color: #FFFFCC;
+	text-decoration: underline;
+}
+div.toc a:visited {
+	color: #D3DED3;
+}
+
+code{
+	font-family: "Courier New",Georgia,helvetica, sans-serif;
+	padding: .1em;
+	color:#835959;
+	font-size: 110%;
+	font-weight:bold ;
+}
+

main.go

-// Copyright 2011 <chaishushan@gmail.com>. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// Password Generator
-//   usage: pwdgen site_name
-package main
-
-import ( 
-	"flag"
-	"os"
-	"fmt"
-	"bufio"
-	"log"
-	"encoding/xml"
-	"encoding/base64"
-	"crypto/md5"
-	"crypto/sha512"
-	"strings"
-	"time"
-)
-
-//-----------------------------------------------------------------------------
-
-// version
-const (
-	majorVersion = 1
-	minorVersion = 1
-	patchVersion = 0
-)
-
-// flags
-var flagConfigFile = flag.String("f", "config.xml", "config file")
-var flagOutputFile = flag.String("o", "", "output file")
-var flagPassword = flag.String("p", "", "global password")
-var flagShowVersion = flag.Bool("v", false, "show version")
-
-func usage() {
-	fmt.Fprintf(os.Stderr,
-		"usage: pwdgen [options] site\n",
-	)
-	flag.PrintDefaults()
-	os.Exit(2)
-}
-
-func input(str string) string { 
-	fmt.Printf("%s", str) 
-	reader := bufio.NewReader(os.Stdin) 
-	input, _ := reader.ReadString('\n') 
-	return strings.TrimSpace(input)
-} 
-
-func parseFlags() {
-	flag.Usage = usage
-	flag.Parse()
-	
-	if *flagShowVersion {
-		fmt.Printf("pwdgen version %d.%d.%d\n",
-			majorVersion, minorVersion, patchVersion,
-		)
-		os.Exit(0)
-	}
-	
-	// site_name
-	if flag.NArg() < 1 { usage() }
-	// password
-	if len(*flagPassword) <= 0 {
-		(*flagPassword) = input("Password: ")
-		if len(*flagPassword) <= 0 { usage() }
-	}
-}
-
-//-----------------------------------------------------------------------------
-// base64 --> base62
-
-// 'i' --> ii
-// '+' --> ip
-// '/' --> is
-// '=' --> ie
-func base64ToBase62(src []byte) []byte {
-	dst := make([]byte, 2*len(src))
-	dstLen := 0
-	
-	for len(src) > 0 {
-		switch src[0] {
-		case 'i':
-			dst[dstLen+0] = 'i'
-			dst[dstLen+1] = 'i'
-			dstLen += 2
-		case '+':
-			dst[dstLen+0] = 'i'
-			dst[dstLen+1] = 'p'
-			dstLen += 2
-		case '/':
-			dst[dstLen+0] = 'i'
-			dst[dstLen+1] = 's'
-			dstLen += 2
-		case '=':
-			dst[dstLen+0] = 'i'
-			dst[dstLen+1] = 'e'
-			dstLen += 2
-			
-		default:
-			dst[dstLen+0] = src[0]
-			dstLen += 1
-		}
-		src = src[1:]
-	}
-	
-	return dst[:dstLen]
-}
-
-//-----------------------------------------------------------------------------
-
-// pwd config struct
-type PwdConfig struct {
-	XMLName xml.Name `xml:"config"`
-
-	Salt    string
-
-	Site    []struct {
-		Name   string `xml:"attr"`
-		Url    string `xml:"attr"`
-
-		Id     string
-		Salt   string
-		Length int
-		
-		pwd    string
-	}
-}
-
-// load config
-func NewPwdConfig(filename string) *PwdConfig {
-	r, err := os.OpenFile(filename, os.O_RDONLY, 0)
-	if err != nil {
-		log.Fatalf("Open config file '%s' fail\n", filename)
-	}
-	defer r.Close()
-
-	var config *PwdConfig
-	if err := xml.Unmarshal(r, &config); err != nil {
-		log.Fatalf("Read config file '%s' fail\n", filename)
-	}
-	
-	return config
-}
-
-// gen password
-// base64(sha(md5(pwd+pwd_salt)+site_id+site_salt))[0:len]
-func (self *PwdConfig)GenPassword(idx int, pwd string) {
-	md5Hash := md5.New()
-	shaHash := sha512.New()
-
-	// md5(pwd+pwd_salt)
-	pwd_salt := self.Salt
-	md5Hash.Write([]byte(pwd+pwd_salt))
-	// md5(pwd+pwd_salt)+site_id+site_salt
-	str := fmt.Sprintf("%x%s%s", md5Hash.Sum(nil),
-		self.Site[idx].Id, self.Site[idx].Salt,
-	)
-	// sha(md5(pwd+pwd_salt)+site_id+site_salt)
-	shaHash.Write([]byte(str))
-	
-	// base64/62(...)
-	encLen := base64.StdEncoding.EncodedLen(len(shaHash.Sum(nil)))
-	encBuf := make([]byte, encLen)
-	base64.StdEncoding.Encode(encBuf, shaHash.Sum(nil))
-	encBuf = base64ToBase62(encBuf)
-
-	// pwd[0:len]
-	length := self.Site[idx].Length
-	self.Site[idx].pwd = string(encBuf[0:length])
-}
-
-// gen all password
-func (self *PwdConfig)GenAllPassword(passord string) {
-	for i := 0; i < len(self.Site); i++ {
-		self.GenPassword(i, passord)
-		time.Sleep(1e7)
-	}
-}
-
-// save password
-func (self *PwdConfig)SavePassword(filename, site_name string) {
-	writer := os.Stdout
-	if len(filename) > 0 {
-		flag := os.O_WRONLY | os.O_CREATE | os.O_TRUNC
-		file, err := os.OpenFile(filename, flag, 0666) 
-		if err != nil {
-			log.Fatalf("Create file '%s' fail\n", filename)
-		}
-		defer file.Close()
-		writer = file
-	}
-	
-	if strings.HasSuffix(filename, ".csv") {
-		// KeePass 1.x format
-		// http://keepass.info/
-		// "Account","Login Name","Password","Web Site","Comments"
-		for i := 0; i < len(self.Site); i++ {
-			if site_name == "*all" || site_name == self.Site[i].Name {
-				fmt.Fprintf(writer, `"%s","%s","%s","%s","%s"%s`,
-					self.Site[i].Name,
-					self.Site[i].Id,
-					self.Site[i].pwd,
-					self.Site[i].Url,
-					"", "\n",
-				)
-			}
-		}
-	} else {
-		for i := 0; i < len(self.Site); i++ {
-			if site_name == "*all" || site_name == self.Site[i].Name {
-				fmt.Fprintf(writer, "%s\n", self.Site[i].Url)
-				fmt.Fprintf(writer, "  id: %s\n", self.Site[i].Id)
-				fmt.Fprintf(writer, "  pd: %s\n", self.Site[i].pwd)
-				fmt.Fprintf(writer, "\n")
-			}
-		}
-	}
-}
-
-//-----------------------------------------------------------------------------
-
-// usage: pwdgen site_name
-func main() {
-	parseFlags()
-	
-	conf := NewPwdConfig(*flagConfigFile)
-	conf.GenAllPassword(*flagPassword)
-	conf.SavePassword(*flagOutputFile, flag.Arg(0))
-}
-
-//-----------------------------------------------------------------------------
-
-
Binary file added.
+pwdgen 1.2.2
+@rem Copyright 2011 <chaishushan@gmail.com>. All rights reserved.
+@rem Use of this source code is governed by a BSD-style
+@rem license that can be found in the LICENSE file.
+
+@rem pwdgen examples.
+@rem --------------------------------------------------------------------------
+
+pwdgen -unittest
+
+pwdgen -help
+pwdgen -version
+
+@rem --------------------------------------------------------------------------
+@rem config.xml
+
+pwdgen -config=config.xml -output=config_111.txt -encrypt_key=111
+pwdgen -config=config.xml -output=config_111.csv -encrypt_key=111
+pwdgen -config=config.xml -encrypt_key=111
+
+pwdgen -config=config.xml -output=config_abc.txt -encrypt_key=abc
+pwdgen -config=config.xml -output=config_abc.csv -encrypt_key=abc
+pwdgen -config=config.xml -output=config_abc.csv -encrypt_key=abc
+pwdgen -config=config.xml -encrypt_key=abc
+
+@rem --------------------------------------------------------------------------
+@rem encrypt_key: 111
+
+pwdgen -site_id=id0 -site_salt=site0 -length=16 -encrypt_key=111 -encrypt_salt=fuckcsdn
+pwdgen -site_id=id1 -site_salt=site0 -length=16 -encrypt_key=111 -encrypt_salt=fuckcsdn
+pwdgen -site_id=id3 -site_salt=site0 -length=16 -encrypt_key=111 -encrypt_salt=fuckcsdn
+
+pwdgen -site_id=id0 -site_salt=site1 -length=12 -encrypt_key=111 -encrypt_salt=fuckcsdn
+pwdgen -site_id=id1 -site_salt=site1 -length=12 -encrypt_key=111 -encrypt_salt=fuckcsdn
+
+pwdgen -site_id=id0 -site_salt=site2 -length=8 -encrypt_key=111 -encrypt_salt=fuckcsdn
+pwdgen -site_id=id0 -site_salt=site3 -length=8 -encrypt_key=111 -encrypt_salt=fuckcsdn
+pwdgen -site_id=id0 -site_salt=site4 -length=8 -encrypt_key=111 -encrypt_salt=fuckcsdn
+pwdgen -site_id=id0 -site_salt=site5 -length=8 -encrypt_key=111 -encrypt_salt=fuckcsdn
+pwdgen -site_id=id0 -site_salt=site6 -length=8 -encrypt_key=111 -encrypt_salt=fuckcsdn
+pwdgen -site_id=id0 -site_salt=site7 -length=8 -encrypt_key=111 -encrypt_salt=fuckcsdn
+pwdgen -site_id=id0 -site_salt=site8 -length=8 -encrypt_key=111 -encrypt_salt=fuckcsdn
+pwdgen -site_id=id0 -site_salt=site9 -length=8 -encrypt_key=111 -encrypt_salt=fuckcsdn
+
+@rem --------------------------------------------------------------------------
+@rem encrypt_key: abc
+
+pwdgen -site_id=id0 -site_salt=site0 -length=16 -encrypt_key=abc -encrypt_salt=fuckcsdn
+pwdgen -site_id=id1 -site_salt=site0 -length=16 -encrypt_key=abc -encrypt_salt=fuckcsdn
+pwdgen -site_id=id3 -site_salt=site0 -length=16 -encrypt_key=abc -encrypt_salt=fuckcsdn
+
+pwdgen -site_id=id0 -site_salt=site1 -length=12 -encrypt_key=abc -encrypt_salt=fuckcsdn
+pwdgen -site_id=id1 -site_salt=site1 -length=12 -encrypt_key=abc -encrypt_salt=fuckcsdn
+
+pwdgen -site_id=id0 -site_salt=site2 -length=8 -encrypt_key=abc -encrypt_salt=fuckcsdn
+pwdgen -site_id=id0 -site_salt=site3 -length=8 -encrypt_key=abc -encrypt_salt=fuckcsdn
+pwdgen -site_id=id0 -site_salt=site4 -length=8 -encrypt_key=abc -encrypt_salt=fuckcsdn
+pwdgen -site_id=id0 -site_salt=site5 -length=8 -encrypt_key=abc -encrypt_salt=fuckcsdn
+pwdgen -site_id=id0 -site_salt=site6 -length=8 -encrypt_key=abc -encrypt_salt=fuckcsdn
+pwdgen -site_id=id0 -site_salt=site7 -length=8 -encrypt_key=abc -encrypt_salt=fuckcsdn
+pwdgen -site_id=id0 -site_salt=site8 -length=8 -encrypt_key=abc -encrypt_salt=fuckcsdn
+pwdgen -site_id=id0 -site_salt=site9 -length=8 -encrypt_key=abc -encrypt_salt=fuckcsdn
+
+@rem --------------------------------------------------------------------------
+@rem encrypt_key: ???
+
+pwdgen -site_id=id0 -site_salt=site0 -length=16 -encrypt_salt=fuckcsdn
+pwdgen -site_id=id0 -site_salt=site0 -length=16 -encrypt_salt=fuckcsdn
+
+@rem --------------------------------------------------------------------------
+@rem invalid
+
+@rem pwdgen -site_id=id0 -config=config.xml -encrypt_key=111
+
+@rem --------------------------------------------------------------------------
+
+PAUSE
+
+

src/CMakeLists.txt

+# Copyright 2011 <chaishushan@gmail.com>. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+project(PWDGEN)
+
+#------------------------------------------------------------------------------
+
+if(WIN32)
+  include_directories(AFTER
+    ./msvc
+  )
+endif()
+
+#------------------------------------------------------------------------------
+# gflags
+
+if(WIN32)
+  include_directories(AFTER
+    ./gflags/src/windows
+    ./gflags/src
+  )
+  set(GFLAGS_SRC
+    ./gflags/src/windows/port.cc
+    ./gflags/src/gflags.cc
+    ./gflags/src/gflags_reporting.cc
+    ./gflags/src/gflags_completions.cc
+  )
+  
+endif()
+if(UNIX)
+  include_directories(AFTER
+    ./gflags/src/linux
+    ./gflags/src
+  )
+  set(GFLAGS_SRC
+    ./gflags/src/gflags.cc
+    ./gflags/src/gflags_reporting.cc
+    ./gflags/src/gflags_completions.cc
+  )
+endif()
+
+#------------------------------------------------------------------------------
+# gtest
+
+include_directories(AFTER
+  ./gtest/include
+  ./gtest
+)
+set(GTEST_SRC
+  ./gtest/src/gtest-all.cc
+)
+
+#------------------------------------------------------------------------------
+# tinyxml
+
+include_directories(AFTER
+  ./tinyxml
+)
+set(TINYXML_SRC
+  ./tinyxml/tinystr.h
+  ./tinyxml/tinyxml.h
+  ./tinyxml/tinystr.cpp
+  ./tinyxml/tinyxml.cpp
+  ./tinyxml/tinyxmlerror.cpp
+  ./tinyxml/tinyxmlparser.cpp
+)
+
+#------------------------------------------------------------------------------
+
+include_directories(AFTER
+  .
+  ./md5
+  ./sha2
+  ./base64
+)
+
+add_executable(pwdgen
+  ./main.cpp
+  ./password_generator.h
+  ./password_generator.cpp
+  ./password_factory.h
+  ./password_factory.cpp
+  ./password_unittest.cpp
+  
+  ./md5/md5.h
+  ./md5/md5.cpp
+  ./sha2/sha2.h
+  ./sha2/sha2.c
+  ./base64/base64.h
+  ./base64/base64.cpp
+  
+  ${TINYXML_SRC}
+  ${GFLAGS_SRC}
+  ${GTEST_SRC}
+)
+install(
+  TARGETS pwdgen
+  RUNTIME DESTINATION .
+)
+
+#------------------------------------------------------------------------------
+

src/base64/base64.cpp

+/* 
+   base64.cpp and base64.h
+
+   Copyright (C) 2004-2008 René Nyffenegger
+
+   This source code is provided 'as-is', without any express or implied
+   warranty. In no event will the author be held liable for any damages
+   arising from the use of this software.
+
+   Permission is granted to anyone to use this software for any purpose,
+   including commercial applications, and to alter it and redistribute it
+   freely, subject to the following restrictions:
+
+   1. The origin of this source code must not be misrepresented; you must not
+      claim that you wrote the original source code. If you use this source code
+      in a product, an acknowledgment in the product documentation would be
+      appreciated but is not required.
+
+   2. Altered source versions must be plainly marked as such, and must not be
+      misrepresented as being the original source code.
+
+   3. This notice may not be removed or altered from any source distribution.
+
+   René Nyffenegger rene.nyffenegger@adp-gmbh.ch
+
+*/
+
+#include "base64.h"
+#include <iostream>
+
+static const std::string base64_chars = 
+             "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+             "abcdefghijklmnopqrstuvwxyz"
+             "0123456789+/";
+
+
+static inline bool is_base64(unsigned char c) {
+  return (isalnum(c) || (c == '+') || (c == '/'));
+}
+
+std::string base64_encode(unsigned char const* bytes_to_encode, unsigned int in_len) {
+  std::string ret;
+  int i = 0;
+  int j = 0;
+  unsigned char char_array_3[3];
+  unsigned char char_array_4[4];
+
+  while (in_len--) {
+    char_array_3[i++] = *(bytes_to_encode++);
+    if (i == 3) {
+      char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
+      char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
+      char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
+      char_array_4[3] = char_array_3[2] & 0x3f;
+
+      for(i = 0; (i <4) ; i++)
+        ret += base64_chars[char_array_4[i]];
+      i = 0;
+    }
+  }
+
+  if (i)
+  {
+    for(j = i; j < 3; j++)
+      char_array_3[j] = '\0';
+
+    char_array_4[0] = (char_array_3[0] & 0xfc) >> 2;
+    char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4);
+    char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6);
+    char_array_4[3] = char_array_3[2] & 0x3f;
+
+    for (j = 0; (j < i + 1); j++)
+      ret += base64_chars[char_array_4[j]];
+
+    while((i++ < 3))
+      ret += '=';
+
+  }
+
+  return ret;
+
+}
+
+std::string base64_decode(std::string const& encoded_string) {
+  int in_len = encoded_string.size();
+  int i = 0;
+  int j = 0;
+  int in_ = 0;
+  unsigned char char_array_4[4], char_array_3[3];
+  std::string ret;
+
+  while (in_len-- && ( encoded_string[in_] != '=') && is_base64(encoded_string[in_])) {
+    char_array_4[i++] = encoded_string[in_]; in_++;
+    if (i ==4) {
+      for (i = 0; i <4; i++)
+        char_array_4[i] = base64_chars.find(char_array_4[i]);
+
+      char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
+      char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
+      char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+
+      for (i = 0; (i < 3); i++)
+        ret += char_array_3[i];
+      i = 0;
+    }
+  }
+
+  if (i) {
+    for (j = i; j <4; j++)
+      char_array_4[j] = 0;
+
+    for (j = 0; j <4; j++)
+      char_array_4[j] = base64_chars.find(char_array_4[j]);
+
+    char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4);
+    char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2);
+    char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3];
+
+    for (j = 0; (j < i - 1); j++) ret += char_array_3[j];
+  }
+
+  return ret;
+}
+

src/base64/base64.h

+
+#ifndef BASE64_H_
+#define BASE64_H_
+
+#include <string>
+
+std::string base64_encode(unsigned char const* s, unsigned int len);
+std::string base64_decode(std::string const& s);
+
+#endif  // BASE64_H_

src/base64/demo.cpp

+#include "base64.h"
+#include <iostream>
+
+int main() {
+  const std::string s = "ADP GmbH\nAnalyse Design & Programmierung\nGesellschaft mit beschränkter Haftung" ;
+
+  std::string encoded = base64_encode(reinterpret_cast<const unsigned char*>(s.c_str()), s.length());
+  std::string decoded = base64_decode(encoded);
+
+  std::cout << "encoded: " << encoded << std::endl;
+  std::cout << "decoded: " << decoded << std::endl;
+
+  return 0;
+}
+
+@rem Build proj with Cmake/MSVC
+@rem ChaiShushan<chaishushan@gmail.com>.
+
+@rem --------------------------------------------------------------------------
+@rem build
+
+mkdir zz_build_tmp
+cd    zz_build_tmp
+
+cmake ..^
+  -G "NMake Makefiles"^
+  -DCMAKE_BUILD_TYPE=release^
+  -DCMAKE_INSTALL_PREFIX=..^
+  ^
+  -DCMAKE_C_FLAGS_DEBUG="/MTd /Zi /Od /Ob0 /RTC1"^
+  -DCMAKE_CXX_FLAGS_DEBUG="/MTd /Zi /Od /Ob0 /RTC1"^
+  ^
+  -DCMAKE_C_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG"^
+  -DCMAKE_CXX_FLAGS_RELEASE="/MT /O2 /Ob2 /DNDEBUG"^
+  ^
+  -DCMAKE_EXE_LINKER_FLAGS="/MANIFEST:NO"
+  
+nmake VERBOSE=1
+nmake install
+
+@rem --------------------------------------------------------------------------
+cd ..
+PAUSE

src/config_example.xml

+<?xml version="1.0" encoding="utf-8" ?>
+
+<!-- test -->
+<config>
+    <!-- global salt -->
+    <salt>fuckcsdn</salt>
+    
+    <!-- site0: id0/id1/id2 -->
+    <site name="site0-0" url="http://www.site0.com/">
+        <id>id0</id>
+        <salt>site0</salt>
+        <length>16</length>
+        <comment>comment</comment>
+    </site>
+    <site name="site0-1" url="http://www.site0.com/">
+        <id>id1</id>
+        <salt>site0</salt>
+        <length>16</length>
+    </site>
+    <site name="site0-2" url="http://www.site0.com/">
+        <id>id3</id>
+        <salt>site0</salt>
+        <length>16</length>
+        <comment>comment</comment>
+    </site>
+    
+    <!-- site1: id0/id1 -->
+    <site name="site1-0" url="http://www.site1.com/">
+        <id>id0</id>
+        <salt>site1</salt>
+        <length>12</length>
+    </site>
+    <site name="site1-1" url="http://www.site1.com/">
+        <id>id1</id>
+        <salt>site1</salt>
+        <length>12</length>
+    </site>
+    
+    <!-- site2/.../site9 -->
+    <site name="site2" url="http://www.site2.com/">
+        <id>id0</id>
+        <salt>site2</salt>
+        <length>8</length>
+    </site>
+    <site name="site3" url="http://www.site3.com/">
+        <id>id0</id>
+        <salt>site3</salt>
+        <length>8</length>
+    </site>
+    <site name="site4" url="http://www.site4.com/">
+        <id>id0</id>
+        <salt>site4</salt>
+        <length>8</length>
+    </site>
+    <site name="site5" url="http://www.site5.com/">
+        <id>id0</id>
+        <salt>site5</salt>
+        <length>8</length>
+    </site>
+    <site name="site6" url="http://www.site6.com/">
+        <id>id0</id>
+        <salt>site6</salt>
+        <length>8</length>
+    </site>
+    <site name="site7" url="http://www.site7.com/">
+        <id>id0</id>
+        <salt>site7</salt>
+        <length>8</length>
+    </site>
+    <site name="site8" url="http://www.site8.com/">
+        <id>id0</id>
+        <salt>site8</salt>
+        <length>8</length>
+    </site>
+    <site name="site9" url="http://www.site9.com/">
+        <id>id0</id>
+        <salt>site9</salt>
+        <length>8</length>
+    </site>
+    
+</config>

src/gflags/AUTHORS

+opensource@google.com
+

src/gflags/CMakeLists.txt

+# Copyright 2011 <chaishushan@gmail.com>. All rights reserved.
+# Use of this source code is governed by a BSD-style
+# license that can be found in the LICENSE file.
+
+project(GFLAGS)
+
+#------------------------------------------------------------------------------
+# gflags lib
+
+if(WIN32)
+  add_definitions(
+    -DGFLAGS_DLL_DECL=""
+  )
+  include_directories(AFTER
+    ./src/windows
+    ./src
+  )
+  set(DEP_LIBS
+  )
+  
+  set(GFLAGS_SRC
+    ./src/windows/port.cc
+    ./src/gflags.cc
+    ./src/gflags_reporting.cc
+    ./src/gflags_completions.cc
+  )
+  
+endif()
+if(UNIX)
+  add_definitions(
+    -DGFLAGS_DLL_DECL=""
+  )
+  include_directories(AFTER
+    ./src/linux
+    ./src
+  )
+  set(DEP_LIBS
+  )
+  
+  set(GFLAGS_SRC
+    ./src/gflags.cc
+    ./src/gflags_reporting.cc
+    ./src/gflags_completions.cc
+  )
+endif()
+
+#------------------------------------------------------------------------------
+
+add_library(gflagslib STATIC
+  ${GFLAGS_SRC}
+)
+set_target_properties(gflagslib
+  PROPERTIES OUTPUT_NAME "gflags"
+)
+
+if(NOT MY_BUILD_TYPE_LIB_ONLY)
+  add_executable(gflagsdemo
+    ./example/main.cpp
+  )
+  target_link_libraries(gflagsdemo gflagslib ${DEP_LIBS})
+endif()
+
+#------------------------------------------------------------------------------
+
+install(TARGETS gflagslib
+  RUNTIME DESTINATION bin
+  LIBRARY DESTINATION lib
+  ARCHIVE DESTINATION lib
+)
+
+#------------------------------------------------------------------------------
+
+

src/gflags/COPYING

+Copyright (c) 2006, Google Inc.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+copyright notice, this list of conditions and the following disclaimer
+in the documentation and/or other materials provided with the
+distribution.
+    * Neither the name of Google Inc. nor the names of its
+contributors may be used to endorse or promote products derived from
+this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

src/gflags/ChangeLog

+Fri Jul 29 19:05:21 2011  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 1.6
+	* BUGFIX: Fix a bug where we were leaving out a required $(top_srcdir)
+	* Fix definition of clstring (jyrki)
+	* Split up flag declares into its own file (jyrki)
+	* Add --version support (csilvers)
+	* Update the README for gflags with static libs
+	* Update acx_pthread.m4 for nostdlib
+	* Change ReparseCommandLineFlags to return void (csilvers)
+	* Some doc typofixes and example augmentation (various)
+
+Mon Jan 24 16:11:35 2011  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 1.5
+	* Better reporting of current vs default value (handler)
+	* Add API for cleaning up of memory at program-exit (jmarantz)
+	* Fix macros to work inside namespaces (csilvers)
+	* Use our own string typedef in case string is redefined (csilvers)
+	* Updated to autoconf 2.65
+
+Wed Oct 13 17:40:12 2010  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 1.4
+	* Add a check to prevent passing 0 to DEFINE_string (jorg)
+	* Reduce compile (.o) size (jyrki)
+	* Some small changes to quiet debug compiles (alexk)
+	* PORTING: better support static linking on windows (csilvers)
+	* DOCUMENTATION: change default values, use validators, etc.
+	* Update the NEWS file to be non-empty
+	* Add pkg-config (.pc) files for libgflags and libgflags_nothreads
+
+Mon Jan  4 18:09:30 2010  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 1.3
+	* PORTABILITY: can now build and run tests under MSVC (csilvers)
+	* Remove the python gflags code, which is now its own package (tansell)
+	* Clarify that "last flag wins" in the docs (csilvers)
+	* Comment danger of using GetAllFlags in validators (wojtekm)
+	* PORTABILITY: Some fixes necessary for c++0x (mboerger)
+	* Makefile fix: $(srcdir) -> $(top_srcdir) in one place (csilvres)
+	* INSTALL: autotools to autoconf v2.64 + automake v1.11 (csilvers)
+
+Thu Sep 10 12:53:04 2009  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 1.2
+	* PORTABILITY: can now build and run tests under mingw (csilvers)
+	* Using a string arg for a bool flag is a compile-time error (rbayardo)
+	* Add --helpxml to gflags.py (salcianu)
+	* Protect against a hypothetical global d'tor mutex problem (csilvers)
+	* BUGFIX: can now define a flag after 'using namespace google' (hamaji)
+
+Tue Apr 14 12:35:25 2009  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 1.1
+	* Add both foo and nofoo for boolean flags, with --undefok (andychu)
+	* Better document how validators work (wojtekm)
+	* Improve binary-detection for bash-completion (mtamsky)
+	* Python: Add a concept of "key flags", used with --help (salcianu)
+	* Python: Robustify flag_values (salcianu)
+	* Python: Add a new DEFINE_bool alias (keir, andrewliu)
+	* Python: Do module introspection based on module name (dsturtevant)
+	* Fix autoconf a bit better, especially on windows and solaris (ajenjo)
+	* BUG FIX: gflags_nothreads was linking against the wrong lib (ajenjo)
+	* BUG FIX: threads-detection failed on FreeBSD; replace it (ajenjo)
+	* PORTABILITY: Quiet an internal compiler error with SUSE 10 (csilvers)
+	* PORTABILITY: Update deb.sh for more recenty debuilds (csilvers)
+	* PORTABILITY: #include more headers to satify new gcc's (csilvers)
+	* INSTALL: Updated to autoconf 2.61 and libtool 1.5.26 (csilvers)
+
+Fri Oct  3 15:16:46 2008  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 1.0
+	* Add a missing newline to an error string (bcmills)
+	* (otherwise exactly the same as gflags 1.0rc2)
+
+Thu Sep 18 12:58:05 2008  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 1.0rc2
+	* Report current flag values in --helpxml (hdn)
+	* Fix compilation troubles with gcc 4.3.3 (simonb)
+	* BUG FIX: I was missing a std:: in DECLARE_string (csilvers)
+	* BUG FIX: Clarify in docs how to specify --bool flags (csilvers)
+	* BUG FIX: Fix --helpshort for source files not in a subdir (csilvers)
+	* BUG FIX: Fix python unittest for 64-bit builds (bcmills)
+	
+Tue Aug 19 16:15:48 2008
+
+	* google-gflags: version 1.0rc1
+	* Move #include files from google/ to gflags/ (csilvers)
+	* Small optimizations to reduce binary (library) size (jyrki)
+	* BUGFIX: forgot a std:: in one of the .h files (csilvers)
+	* Speed up locking by making sure calls are inlined (ajenjo)
+	* 64-BIT COMPATIBILITY: Use %PRId64 instead of %lld (csilvers)
+	* PORTABILITY: fix Makefile to work with Cygwin (ajenjo)
+	* PORTABILITY: fix code to compile under Visual Studio (ajenjo)
+	* PORTABILITY: fix code to compile under Solaris 10 with CC (csilvers)
+
+Mon Jul 21 23:01:38 2008  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 0.9
+	* Add the ability to validate a command-line flag (csilvers)
+	* Add completion support for commandline flags in bash (daven)
+	* Add -W compile flags to Makefile, when using gcc (csilvers)
+	* Allow helpstring to be NULL (cristianoc)
+	* Improved documentation of classes in the .cc file (csilvers)
+	* Fix python bug with AppendFlagValues + shortnames (jjtswan)
+	* Use bool instead of int for boolean flags in gflags.py (bcmills)
+	* Simplify the way we declare flags, now more foolproof (csilvers)
+	* Better error messages when bool flags collide (colohan)
+	* Only evaluate DEFINE_foo macro args once (csilvers)
+
+Wed Mar 26 15:20:18 2008  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 0.8
+	* Export DescribeOneFlag() in the API
+	* Add support for automatic line wrapping at 80 cols for gflags.py
+	* Bugfix: do not treat an isolated "-" the same as an isolated "--"
+	* Update rpm spec to point to Google Code rather than sourceforge (!)
+	* Improve documentation (including documenting thread-safety)
+	* Improve #include hygiene
+	* Improve testing
+	
+Thu Oct 18 11:33:20 2007  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 0.7
+	* Deal even more correctly with libpthread not linked in (csilvers)
+	* Add STRIP_LOG, an improved DO_NOT_SHOW_COMMANDLINE_HELP (sioffe)
+	* Be more accurate printing default flag values in --help (dsturtevant)
+	* Reduce .o file size a bit by using shorter namespace names (jeff)
+	* Use relative install path, so 'setup.py --home' works (csilvers)
+	* Notice when a boolean flag has a non-boolean default (bnmouli)
+	* Broaden --helpshort to match foo-main.cc and foo_main.cc (hendrie)
+	* Fix "no modules match" message for --helpshort, etc (hendrie)
+
+Wed Aug 15 07:35:51 2007  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 0.6
+	* Deal correctly with case that libpthread is not linked in (csilvers)
+	* Update Makefile/tests so we pass "make distcheck" (csilvers)
+	* Document and test that last assignment to a flag wins (wan)
+
+Tue Jun 12 15:23:42 2007  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 0.5
+	* Include all m4 macros in the distribution (csilvers)
+	* Python: Fix broken data_files field in setup.py (sidlon)
+	* Python: better string serliaizing and unparsing (abo, csimmons)
+	* Fix checks for NaN and inf to work with Mac OS X (csilvers)
+	
+Thu Apr 19 15:15:07 2007  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 0.4
+	* Remove is_default from GetCommandLineFlagInfo (csilvers)
+	* Portability fixes: includes, strtoll, gcc4.3 errors (csilvers)
+	* A few doc typo cleanups (csilvers)
+
+Wed Mar 28 12:15:56 2007  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 0.3
+	* python portability fix: use popen instead of subprocess (csilvers)
+	* Add is_default to CommandLineFlagInfo (pchien)
+	* Make docs a bit prettier (csilvers)
+	* Actually include the python files in the distribution! :-/ (csilvers)
+
+Mon Jan 22 15:33:06 2007  Google Inc. <opensource@google.com>
+
+	* google-gflags: version 0.2
+	* added support for python commandlineflags, as well as c++
+	* gflags2man, a script to turn flags into a man page (dchristian)
+
+Wed Dec 13 12:37:19 2006  Google Inc. <opensource@google.com>
+
+	* google-gflags: initial release:
+	The gflags package contains a library that implements commandline
+	flags processing.  As such it's a replacement for getopt().  It
+	has increased flexibility, including built-in support for C++
+	types like string, and the ability to define flags in the source
+	file in which they're used.
+== 29 July 2011 ==
+
+I've just released gflags 1.6.  The major new feature in this release
+is support for setting version info, so that --version does something
+useful.
+
+One minor change has required bumping the library number:
+`ReparseCommandlineFlags` now returns `void` instead of `int` (the int
+return value was always meaningless).  Though I doubt anyone ever used
+this (meaningless) return value, technically it's a change to the ABI
+that requires a version bump.  A bit sad.
+
+There's also a procedural change with this release: I've changed the
+internal tools used to integrate Google-supplied patches for gflags
+into the opensource release.  These new tools should result in more
+frequent updates with better change descriptions.  They will also
+result in future `ChangeLog` entries being much more verbose (for better
+or for worse).
+
+See the
+[http://code.google.com/p/google-gflags/source/browse/tags/gflags-1.6/ChangeLog ChangeLog]
+for a full list of changes for this release.
+
+=== 24 January 2011 ===
+
+I've just released gflags 1.5.  This release has only minor changes
+from 1.4, including some slightly better reporting in --help, and
+an new memory-cleanup function that can help when running gflags-using
+libraries under valgrind.  The major change is to fix up the macros
+(`DEFINE_bool` and the like) to work more reliably inside namespaces.
+
+If you have not had a problem with these macros, and don't need any of
+the other changes described, there is no need to upgrade.  See the
+[http://code.google.com/p/google-gflags/source/browse/tags/gflags-1.5/ChangeLog ChangeLog]
+for a full list of changes for this release.
+
+=== 11 October 2010 ===
+
+I've just released gflags 1.4.  This release has only minor changes
+from 1.3, including some documentation tweaks and some work to make
+the library smaller.  If 1.3 is working well for you, there's no
+particular reason to upgrade.
+
+=== 4 January 2010 ===
+
+I've just released gflags 1.3.  gflags now compiles under MSVC, and
+all tests pass.  I *really* never thought non-unix-y Windows folks
+would want gflags, but at least some of them do.
+
+The major news, though, is that I've separated out the python package
+into its own library, [http://code.google.com/p/python-gflags python-gflags].
+If you're interested in the Python version of gflags, that's the place to
+get it now.
+
+=== 10 September 2009 ==
+
+I've just released gflags 1.2.  The major change from gflags 1.1 is it
+now compiles under MinGW (as well as cygwin), and all tests pass.  I
+never thought Windows folks would want unix-style command-line flags,
+since they're so different from the Windows style, but I guess I was
+wrong!
+
+The other changes are minor, such as support for --htmlxml in the
+python version of gflags.
+
+=== 15 April 2009 ===
+
+I've just released gflags 1.1.  It has only minor changes fdrom gflags
+1.0 (see the
+[http://code.google.com/p/google-gflags/source/browse/tags/gflags-1.1/ChangeLog ChangeLog]
+for details).  The major change is that I moved to a new
+system for creating .deb and .rpm files.  This allows me to create
+x86_64 deb and rpm files.
+
+In the process of moving to this new system, I noticed an
+inconsistency: the tar.gz and .rpm files created libraries named
+libgflags.so, but the deb file created libgoogle-gflags.so.  I have
+fixed the deb file to create libraries like the others.  I'm no expert
+in debian packaging, but I believe this has caused the package name to
+change as well.  Please let me know (at
+[mailto:google-gflags@googlegroups.com
+google-gflags@googlegroups.com]) if this causes problems for you --
+especially if you know of a fix!  I would be happy to change the deb
+packages to add symlinks from the old library name to the new
+(libgoogle-gflags.so -> libgflags.so), but that is beyond my knowledge
+of how to make .debs.
+
+If you've tried to install a .rpm or .deb and it doesn't work for you,
+let me know.  I'm excited to finally have 64-bit package files, but
+there may still be some wrinkles in the new system to iron out.
+
+===1 October 2008===