HashCrack程序规划
最近几天在思考如何遍历md5找出原码字符串,但九十多个可见字符,96^6 782757789696,就算只遍历6位组合也是非常惊人的巨量数据,单机根本无法完成,根据常用密码合成规律,我们可以采用分而治之的方法解决,方法大致如下:
1、 使用很多机器,机器越多覆盖的范围越大。
2、 优先覆盖最常用的范围,如全数字组合,小写字母组合,小写数字混合组合,大写字母组合,夹杂一个非字母数字字符的组合,… 之后覆盖非常见组合,如所有可见字符的N个全排列。
3、 采用c/s结构,中心机管理区段分配策略,优先覆盖常用区段,所有slave和master一起构成一个覆盖网。
4、 不仅支持md5,也支持sha等其他类似算法。
5、 Master和slave也支持添加字典,为了覆盖尽可能多的组合,可添加任何合适的字典组合。
实现难点:
1、 数据组织。
方案一、考虑过磁盘存储方案,研究了sqlite,写效率大概10w/s,加了索引大概5w/s,sqlite存储效率也不是很高,比berkeley存储浪费很多空间,加了索引后空间放大了一倍。也尝试过berkeley方案,写效率大概只有4.5w/s,存储相对sqlite紧凑一些。但由于写效率太低,都难于实现我所希望的一个slave一下分配1亿数据量的模式(1亿数据大概要占磁盘5-10G,最经济模式大概也要占2.xG)。由于对btree+不太熟悉,暂时还没有找到高效的存储方案。
方案二、其实首先是考虑了内存方案,用内存相比磁盘其实要简单一些,不过受机器可用内存的限制以及客户接受程度的限制,难于让一台slave处理1亿以上的数据量,默认大概只能分配2000w-5000w左右的数据量(大概占用内存400M-1.2G)。
以上两种方案其实选择方案一更合适一点,因为一般的机器挤2G左右的磁盘基本都没有问题,甚至20G-200G可能都问题不大,但要持久占用1G内存可能不大好,毕竟大多数用户比容易接受。第一版暂时用了方案二,待高速写存储方案做好后替换一个dll即可(该dll已经留好了接口可直接替换)。
2、 区段划分
单纯的划分某一个区段也是比较容易的,如10个数字的8个组合,可用如下方法表示
Digits = “0123456789”
Range(Digits, 8, 0, 20000000) 表示digits 8个字母的排列 [0,20000000]
但将一些常用区段单独出来之后涉及到和更大范围字母全排列的重合情况就不大好扣出来,暂时没有找到较好的表示方法,好在小范围排列被冗余也问题不是很大,此表示方法待继续研究,暂时采用冗余方案。
3、 Master 发现机制
其实这是一个经典的问题,可考虑得很复杂,也可考虑得很简单,由于我名下几个域名都被禁止解析了,所以这个问题变得不是那么方便,不过暂时还是用个域名部署一下最为简单,存储空间也是个问题,待我联系几个朋友看看能不能找到一个合适的存储地点,待找到后第一版就这么部署出去吧。
实现方法:
由于要有一个中心提供调度方案,因此该系统肯定有一个中心(不管是一个点还是N个点),所以考虑采用c/s模式,第一版采用一个master和N个slave的方案。
master主要实现以下功能:
1、 覆盖最常用区段排列,籍此提供最基本的查询服务。
2、 支持大量slave接入(暂采用iocp模式接入)。
3、 提供区段划分功能,slave接入断开自动分配区段,优先分配常用区段,其次分配非常用区段。
4、 查询转发功能,接收slave的查询请求,转发给其他slave。
slave实现以下功能:
1、 和master交互,接收分配的区段,处理区段内的数据并提供该区段数据查询服务(此功能由一个接口dll实现,可轻易替换)。
2、 支持查询功能。
3、 在客户端还计划支持api,slave是api的proxy,api通过消息向slave发送查询请求,slave通过给master发送查询请求,在整个群落里面提供查询服务,此功能为该体系的一大亮点,暂时没考虑做什么限制,主要为吸引用户提供很主动的编程功能,第一版通过一个c的dll提供api调用功能,在此api基础上用户应该可以很容易包装出其他语言的调用接口,如lua、python的接口等。
进度说明:
由于该项目只是一个即兴性项目,没打算耗费很多时间,计划在一周内完成,已经过去了3天,所以在细节上暂时无法抽出很多时间仔细研究,待整体功能成型后看情况再斟酌算法,易改变部分暂时都用接口dll实现,该项目代码部分大概完成了一半左右,未来2-3天左右大概可以做完第一版。