CUDA—使用GPU暴力破解密码

来源:互联网 发布:windows embedded 8.1 编辑:程序博客网 时间:2024/05/29 18:04

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 << "\n经GPU运算破解的用户密码是:" << endl;//输出破解的密码,不足6位前补0cout.fill('0');cout.width(6);  //总长度6位cout << keyWordByGPU << endl << endl;endTime = clock();  //破解耗时,以秒位单位float spendTime = (float)(endTime - startTime) / CLOCKS_PER_SEC;cout << "耗时:\n" << 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\n", 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!\n", cudaStatus);goto Error;}// 把破解的密码从GPU拷贝到CPUcudaStatus = 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的情况:



正常情况:



0 0
原创粉丝点击