ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

暴力破解算法

2021-07-03 14:00:13  阅读:174  来源: 互联网

标签:中继 暴力破解 relayNum relayIndexArr int 算法 设备 relayIndex


暴力破解算法

可用于如下场景:
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;
}

标签:中继,暴力破解,relayNum,relayIndexArr,int,算法,设备,relayIndex
来源: https://blog.csdn.net/canlynetsky/article/details/118439082

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有