暴力破解算法
暴力破解算法
可用于如下场景:
1、密码猜测
2、对于罗拉模块的数据请求,当发现模块么有回应数据时,往往考虑是否模块所处位置导致信号无法到达,此时可借助其他模块作为中继来进行通讯。
当然无论用于哪种场景,都需要自己实现代码,本代码只是写出了核心算法。
算法描述:从1位密码开始,或者说从1个中继开始,从数组中获取每一种值,取到最后一个数据后,翻转到第一个值,增加1位,取第一个值。
比如密码组合有[1,2,3,4]四个数字,密码最多4位,那么组合规律如下:
1
2
3
4
11
12
13
14
…
4444
代码如下:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <time.h>
using namespace std;
typedef unsigned int BOOL;
typedef unsigned short u16;
#define TRUE 1
#define FALSE 0
#define DEVICE_COUNT 4 // 设备数量
#define MAX_RELAY_NUM 3 // 最大中继数量
int relayNum = 0; // 当前中继数量
int devices[DEVICE_COUNT] = { 1,2,3,4}; // 设备地址数组
int relayIndexArr[DEVICE_COUNT] = { 0}; // 中继索引数组,存储设备序号,如0,1
int relayDevices[DEVICE_COUNT] = { 0}; // 中继数组,存储设备地址,如1,2
/** * @brief 改变中继地址,策略为暴力算法,先尝试1个中继,然后2个,与暴力破解密码是一个逻辑 * * 比如有设备1/2/3/4共4台设备,要访问设备4,但是没返回数据,这时开始中继。 * 首先尝试1个中继,有4种可能:分别为1/2/3/4. * 然后考虑2个中继,有4 * 4 = 16种可能,分别为:11,12,13,14,21,22...,44 * 然而上述排序中应该排除2种情况: * 情况1:中继中不能存在自己; * 情况2:中继中不能重复设备; * 排除的情况单独用函数判断,如果被排除,再获取下一种情况即可。这样做能让改变中继函数变得简单。 * @return BOOL 获取到中继返回TRUE,否则返回FALSE; */
static BOOL ChangeDeviceRelayAddrs()
{
int relayIndex = relayNum - 1; // 注意数据类型,第一次为-1
while (relayIndex >= 0)
{
// 所有设备都用过了,返回使用第一个设备作为中继,然后修改前面一个中继设备的地址(前面一个中继的序号加1)
// 比如设备1,2,3,4共4台设备,当2个中继时:为14组合,那么下一次应该为21组合。
if (relayDevices[relayIndex] == devices[DEVICE_COUNT - 1])
{
relayIndexArr[relayIndex] = 0;
relayDevices[relayIndex] = devices[relayIndexArr[relayIndex]];
--relayIndex;
continue;
}
// 当前中继还未达到最后那台设备,修改当前中继为下一台设备,并返回TRUE
++relayIndexArr[relayIndex];
relayDevices[relayIndex] = devices[relayIndexArr[relayIndex]];
return TRUE;
}
// 循环完成还没有找到有效中继,说明所有中继都已经回滚为第一台设备了,那么中继数量加1。
relayNum++;
if (relayNum <= MAX_RELAY_NUM)
{
relayIndex = relayNum - 1;
relayIndexArr[relayIndex] = 0;
relayDevices[relayIndex] = devices[relayIndexArr[relayIndex]];
return TRUE;
}
// 如果已经超过最大中继数量,就将设备重置为无中继状态
memset(relayIndexArr, 0, sizeof relayIndexArr);
memset(relayDevices, 0, sizeof relayDevices);
relayNum = 0;
return TRUE;
}
/** * @brief 改变中继地址,策略为暴力算法,先尝试1个中继,然后2个,与暴力破解密码是一个逻辑 * * 比如有设备1/2/3/4共4台设备,要访问设备4,但是没返回数据,这时开始中继。 * 首先尝试1个中继,有4种可能:分别为1/2/3/4. * 然后考虑2个中继,有4 * 4 = 16种可能,分别为:11,12,13,14,21,22...,44 * 然而上述排序中应该排除2种情况: * 情况1:中继中不能存在自己; * 情况2:中继中不能重复设备; * 排除的情况单独用函数判断,如果被排除,再获取下一种情况即可。这样做能让改变中继函数变得简单。 * @param deviceIndex 需要中继的设备序号。 * @return BOOL 获取到中继返回TRUE,否则返回FALSE; */
static BOOL IsRelayAddrValid(u16 deviceIndex)
{
for (int i = 0; i < relayNum; i++)
{
if (relayIndexArr[i] == deviceIndex)
{
return FALSE; // 包含了自己
}
}
for (int i = 0; i < relayNum; i++)
{
for (int j = i + 1; j < relayNum; j++)
{
if (relayIndexArr[i] == relayIndexArr[j])
{
return FALSE; // 两个中继重复了
}
}
}
return TRUE;
}
static void PrintRelays(BOOL valid)
{
if (relayNum == 0)
{
cout << "无中继" << endl;
return;
}
cout << (valid ? "发现有效中继:" : "无效中继:");
for (int i = 0; i < relayNum; i++)
{
cout << relayDevices[i];
}
cout << endl;
}
int main(int, char **)
{
int deviceIndex = 0;
do
{
while (1)
{
ChangeDeviceRelayAddrs();
if (IsRelayAddrValid(deviceIndex))
{
PrintRelays(TRUE);
break;
}
else
{
PrintRelays(FALSE);
}
}
} while (relayNum != 0);
return 0;
}
还没有评论,来说两句吧...