zoukankan      html  css  js  c++  java
  • CUDA—使用GPU暴力破解密码

    GPU支持大规模的并行加速运算,胜在量上,CPU处理大量的并行运算显得力不从心,它是胜在逻辑上。利用显卡加速的应用越来越多,但如果说GPU即将或最终将替代CPU还有点言过其实,二者最终将优势互补,各尽所能。


    使用显卡的无脑并行运算破解密码是一个不错的选择。这里选择一种简单的情况,限定密码是6位纯数字,并且不限定输入次数,这种 情况下可以使用GPU暴力破解,当然仅供娱乐,并无任何实际的应用价值。


    #include "cuda_runtime.h"
    #include "device_launch_parameters.h"
    #include <stdio.h>
    #include <iostream>
    #include "time.h"
    
    using namespace std;
    
    //密码破解入口函数
    cudaError_t BreakWithCuda(const int *userKeyWord, int *keyWordByGPU);
    
    //密码破解核函数
    __global__ void BreakPasswordKernel(const int *userKeyWord, int *keyWordByGPU)
    {
    	//获取线程的索引号
    	int blockId = blockIdx.y*gridDim.x + blockIdx.x;
    	int threadID = blockId*blockDim.x + threadIdx.x;
    	if (threadID == *userKeyWord)
    	{
    		*keyWordByGPU = threadID;
    	}
    }
    
    int main()
    {
    	int userWord = 0;  //用户输入的密码
    	int keyWordByGPU = 0;  //接收GPU破解的密码
    	cout << "请输入你设置的密码(6位阿拉伯数字):" << endl;
    	cin >> userWord;
    	const int keyWord = userWord;
    	getchar();
    
    	//计算耗时变量
    	clock_t startTime, endTime;
    	startTime = clock();
    
    	cudaError_t cudaStatus = BreakWithCuda(&keyWord, &keyWordByGPU);
    	if (cudaStatus != cudaSuccess) {
    		fprintf(stderr, "BreakWithCuda failed!");
    		return 1;
    	}
    
    	//重置GPU设备
    	cudaStatus = cudaDeviceReset();
    	if (cudaStatus != cudaSuccess) {
    		fprintf(stderr, "cudaDeviceReset failed!");
    		return 1;
    	}
    
    	cout << "
    经GPU运算破解的用户密码是:" << endl;
    
    	//输出破解的密码,不足6位前补0
    	cout.fill('0');
    	cout.width(6);  //总长度6位
    	cout << keyWordByGPU << endl << endl;
    
    	endTime = clock();  //破解耗时,以秒位单位
    	float spendTime = (float)(endTime - startTime) / CLOCKS_PER_SEC;
    	cout << "耗时:
    " << spendTime << "seconds" << endl;
    
    	getchar();
    	return 0;
    }
    
    cudaError_t BreakWithCuda(const int *userKeyword, int *keyWordByGPU)
    {
    	int *dev_userKeyWord = 0;
    	int *dev_keyWordByGPU = 0;
    	cudaError_t cudaStatus;
    
    	//选择运行设备
    	cudaStatus = cudaSetDevice(0);
    	if (cudaStatus != cudaSuccess) {
    		fprintf(stderr, "cudaSetDevice failed!  Do you have a CUDA-capable GPU installed?");
    		goto Error;
    	}
    
    	// 在GUP上分配显存
    	cudaStatus = cudaMalloc((void**)&dev_userKeyWord, sizeof(int));
    	if (cudaStatus != cudaSuccess) {
    		fprintf(stderr, "cudaMalloc failed!");
    		goto Error;
    	}
    	cudaStatus = cudaMalloc((void**)&dev_keyWordByGPU, sizeof(int));
    	if (cudaStatus != cudaSuccess) {
    		fprintf(stderr, "cudaMalloc failed!");
    		goto Error;
    	}
    
    	// 把用户输入的密码从主机复制到设备显存上
    	cudaStatus = cudaMemcpy(dev_userKeyWord, userKeyword, sizeof(int), cudaMemcpyHostToDevice);
    	if (cudaStatus != cudaSuccess) {
    		fprintf(stderr, "cudaMemcpy failed!");
    		goto Error;
    	}
    
    	dim3 grid(100, 100); //创建一个包含100*100个线程块的Grid    
    	BreakPasswordKernel << <grid, 100 >> > (dev_userKeyWord, dev_keyWordByGPU);
    
    	// GPU运行错误检查
    	cudaStatus = cudaGetLastError();
    	if (cudaStatus != cudaSuccess) {
    		fprintf(stderr, "BreakPasswordKernel launch failed: %s
    ", cudaGetErrorString(cudaStatus));
    		goto Error;
    	}
    
    	// cudaDeviceSynchronize waits for the kernel to finish, and returns
    	// any errors encountered during the launch.
    	cudaStatus = cudaDeviceSynchronize();
    	if (cudaStatus != cudaSuccess) {
    		fprintf(stderr, "cudaDeviceSynchronize returned error code %d after launching BreakPasswordKernel!
    ", cudaStatus);
    		goto Error;
    	}
    
    	// 把破解的密码从GPU拷贝到CPU
    	cudaStatus = cudaMemcpy(keyWordByGPU, dev_keyWordByGPU, sizeof(int), cudaMemcpyDeviceToHost);
    	if (cudaStatus != cudaSuccess) {
    		fprintf(stderr, "cudaMemcpy failed!");
    		goto Error;
    	}
    
    Error:
    	cudaFree(dev_keyWordByGPU);
    	cudaFree(dev_userKeyWord);
    
    	return cudaStatus;
    }
    


    运行后提示用户输入6位密码,第一位可以为0,如果检测到最终破解的密码不足6位,则可以判断用户在第一位输入的数字是0,所以自动在密码前补上0,补足6位


    输入的密码第一位或之后若干位为0的情况:



    正常情况:



  • 相关阅读:
    程序员这口饭职业规划解决方案
    Entity Framework 学习初级篇Entity SQL
    工厂方法模式与IoC/DI 4
    为NUnit制作Visual Studio模板
    Enterprise Architect 7.5(UML工具)集成到Visual Studio中(有下载)
    从事ASP.NET开发两年多,谈谈对两三年工作经验的ASP.NET程序员的基本见解
    模式讲解
    一位软件工程师的7年总结 [转]
    工厂方法模式2
    CodeDom系列1
  • 原文地址:https://www.cnblogs.com/mtcnn/p/9411872.html
Copyright © 2011-2022 走看看