在当今数字化的世界中,保护用户的个人信息变得尤为重要。手机号作为个人敏感信息之一,在数据传输和存储时需要特别注意安全。一种常见的处理方式是通过加密算法对手机号进行加密处理,比如使用MD5(Message Digest Algorithm 5)算法。
虽然MD5不可逆,但是我们可以利用穷举方法 将手机号段 都生成一遍,对应的MD5,再用MD5还原出明文。
说干就干,首先我们得知道现在常见的手机号段
130,131,132,133,134,135,136,137,138,139,150,151,152,153,155,156,157,158,159,170,171,172,173,175,176,177,178,180,181,182,183,184,185,186,187,188,189,191,192,195,196,197,198,199
知道这些手机号段就好办了。 比如
1300000000 - 1309999999 号段的手机号和对应的md5全部生成出来。
我尝试用golang的线程去生成,但是致命缺点 机器配置太低了,一晚上生成了几百万。远远达不到数据要求。
于是奇妙的点子萌生了,之前打游戏买了一块英伟达的4090显卡,并且英伟达官方支持cuda利用GPU运算,如果用这个生成 那岂不是如鱼得水。
下面是cuda简单生成md5的例子
#include <stdio.h>
#include <cuda_runtime.h>
#include <openssl/md5.h> // 使用OpenSSL库来计算MD5
// CUDA kernel: 计算单个字符串的MD5
__global__ void compute_md5(unsigned char* input, unsigned char* output, int length) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
if (idx < length) {
MD5_CTX context;
MD5_Init(&context);
MD5_Update(&context, &input[idx * 11], 11); // 假设手机号码长度为11
MD5_Final(&output[idx * 16], &context); // MD5结果长度为16字节
}
}
int main() {
// 示例:处理10个手机号码
const int numPhones = 10;
const int phoneLength = 11; // 手机号码长度
const int md5Length = 16; // MD5哈希长度
// 在主机端准备输入数据
char* h_input = new char[numPhones * phoneLength];
for(int i = 0; i < numPhones; ++i){
for(int j = 0; j < phoneLength; ++j){
h_input[i * phoneLength + j] = '0' + (i % 10); // 简化示例,实际应用中应替换为真实手机号码
}
}
// 准备输出数据
unsigned char* h_output = new unsigned char[numPhones * md5Length];
// 分配设备内存
unsigned char* d_input;
unsigned char* d_output;
cudaMalloc((void**)&d_input, numPhones * phoneLength * sizeof(char));
cudaMalloc((void**)&d_output, numPhones * md5Length * sizeof(unsigned char));
// 将输入数据从主机复制到设备
cudaMemcpy(d_input, h_input, numPhones * phoneLength * sizeof(char), cudaMemcpyHostToDevice);
// 定义线程块和网格大小
int threadsPerBlock = 256;
int blocksPerGrid = (numPhones + threadsPerBlock - 1) / threadsPerBlock;
// 调用CUDA kernel
compute_md5<<<blocksPerGrid, threadsPerBlock>>>(d_input, d_output, numPhones);
// 将结果从设备复制回主机
cudaMemcpy(h_output, d_output, numPhones * md5Length * sizeof(unsigned char), cudaMemcpyDeviceToHost);
// 打印结果
for(int i = 0; i < numPhones; ++i){
printf("Phone %d MD5: ", i);
for(int j = 0; j < md5Length; ++j){
printf("%02x", h_output[i * md5Length + j]);
}
printf("\n");
}
// 清理
delete[] h_input;
delete[] h_output;
cudaFree(d_input);
cudaFree(d_output);
return 0;
}
于是乎
image.png
都可以毫秒级别还原明文
对应也出了接口
image.png