用QT来访问网站非常简单,使用QNetworkAccessManager即可,还有一系列的辅助类来判断HTTP状态码、重定向等东西。
写这个玩具的过程中,有一个收获,就是实现咯一个“生成器”功能,以前觉得这个功能是难做的。
给出一个模式字符串(例如“<si><pr><da>.<su>”),其中含有关键字(例如“<da>”,表示代入日期字符串),每个关键字表示一种不同类型的字符串,需要在运行时被替换成该关键字对应的字典中的所有可能值。最后要按照这个模式字符串中的关键字组合情况来生成所有可能的字符串。其实就是一个按照手写的规则来组合已有的字典,生成一个庞大的字典的功能,在爆破、穷举中很有用的。
解决思路按照专业术语来说就是“自顶向下,逐步求精”。
在实现的过程中,首先分析一下模式字符串,按照关键字将它分解成几段,不包含关键字的部分也各自成为一段,每一段对应一个生成器实例。例如“<si><pr><da>.<su>”,其中的每个尖括号对都是关键字,于是分解成:
1.<si> 表示网站名字关键字。对应网站名字生成器。会遍历网站名字字典中的所有网站名字,并且对它们进行变换。变换是指使用其它的分割符来代替网站名字中本来的分割符“.”。分割符也是以字典提供的。由于这里有两道工序:遍历字典和替换分割符,所以这里还可以再细分成两个生成器实例,不过本座没这么做。
2.<pr> 表示文件名前缀关键字。对应文件名前缀生成器。会遍历文件名前缀字典中所有的文件名前缀。
3.<da> 表示日期关键字。对应日期生成器。会将给定的开始日期到结束日期之间的日期遍历一遍,并且对每个日期按照不同格式输出。输出格式也是以字典定义的。同样可以细分成两个生成器实例。
4.. 这是一段普通字符串。对应普通字符串生成器。就将字符串按原样输出。
5.<su> 表示文件名后缀关键字。对应文件名后缀生成器。会遍历文件名后缀字典中所有的后缀。
所以,“<si><pr><da>.<su>”就表示:
<网站名字><文件名前缀><日期>.<文件名后缀>
生成之后的一个实例:
stupidbeauty.comSiteScan2012429.cpp
分解咯之后,问题就变成实现具体的生成器咯。每种类型的生成器只负责自己这个类型的字符串的生成,然后将所有生成器按照模式字符串中的位置关系串联起来。每个生成器在将自己对应的字典遍历完咯一遍之后,会发射“进位”信号。串联就是将后面一个生成器的进位信息连接到前一个生成器,这样,后面一个生成器进位之后,就会触发前面一个生成器切换到字典中的下一项。
当要生成一个整体字符串时,依次让每个生成器生成自己当前的字符串,将这些字符串串联起来,便得到符合整个模式字符串要求的字符串咯。然后,告诉最后一个生成器,切换到下一个。如此循环,便得到所有符合模式字符串的字符串咯。
每种生成器在具体的实现中会记录自己当前遍历到的位置(文件名前缀字典遍历到哪个前缀咯)、或者是自己的当前状态(日期生成器的当前日期是哪天),一旦遍历到要越界咯,则发射进位信号,驱动前面一个生成器切换。普通字符串生成器在接收到进位信号之后,直接传递给自己前面一个生成器。
所有类型的生成器都继承自一个基类,其接口也定义在基类中,便于在实际运行过程中用容器串联起来。
至此,就没有什么难度咯。
放到sourceforge上与程序猿们交流:
源代码:
http://sourceforge.net/projects/hxcanstoys/files/SiteScan/SiteScan.src.2012.4.29.rar/download
GNU/Linux预编译,一般情况下是运行不起来的:
http://sourceforge.net/projects/hxcanstoys/files/SiteScan/SiteScan.lin.2012.4.29.zip/download
Windows预编译:
http://sourceforge.net/projects/hxcanstoys/files/SiteScan/SiteScan.win.2012.4.30.7z/download
HxLauncher: Launch Android applications by voice commands