Похоже, что вам нужно ровно две вещи, чтобы достичь того, что вам нужно:
- Разложить беззнаковый входной символ на 16 цифр (которых всегда будет 2)
- Преобразуйте цифры из двух чисел di git base 16 в пару символов ascii, представляющих шестнадцатеричные цифры.
Первый шаг можно выполнить следующим образом:
__device__ __host__ void makedigits(unsigned char x, unsigned char (&digits)[2])
{
unsigned char d0 = x / 16;
digits[1] = x - d0 * 16;
unsigned char d1 = d0 / 16;
digits[0] = d0 - d1 * 16;
}
Это вернет наиболее значимое основание 16 di git в digits[0]
и наименее значимое основание di git в digits[1]
.
Второй шаг может быть сделан простым добавлением смещений к двум 16 цифр для преобразования их в правильные значения ASCII:
__device__ __host__ void makehex(unsigned char (&digits)[2], char (&hex)[2])
{
for(int i=0; i<2; ++i) {
if (digits[i] < 10) {
hex[i] = '0' + digits[i];
} else {
hex[i] = 'a' + (digits[i] - 10);
}
}
}
Полный пример может выглядеть следующим образом:
#include <iostream>
#include <cstdio>
__device__ __host__ void makedigits(unsigned char x, unsigned char (&digits)[2])
{
unsigned char d0 = x / 16;
digits[1] = x - d0 * 16;
unsigned char d1 = d0 / 16;
digits[0] = d0 - d1 * 16;
}
__device__ __host__ void makehex(unsigned char (&digits)[2], char (&hex)[2])
{
for(int i=0; i<2; ++i) {
if (digits[i] < 10) {
hex[i] = '0' + digits[i];
} else {
hex[i] = 'a' + (digits[i] - 10);
}
}
}
__global__ void kernel(unsigned char* input, char* output)
{
for (int i = 0; i < 16; ++i) {
unsigned char val = input[i];
unsigned char d[2];
char h[2];
makedigits(val, d);
makehex(d, h);
output[2*i] = h[0];
output[2*i+1] = h[1];
}
}
int main()
{
unsigned char md5Hash[32];
for(int i=0; i<32; ++i) md5Hash[i] = 255-i;
unsigned char* d_md5Hash;
cudaMalloc(&d_md5Hash, 32 * sizeof(unsigned char));
cudaMemcpy(d_md5Hash, &md5Hash[0], 32 * sizeof(unsigned char),
cudaMemcpyHostToDevice);
char str[16][2];
for (int j = 0; j < 16; ++j) {
sprintf(str[j], "%02x", md5Hash[j]);//convert by 2 symbols
}
for(int i=0; i<16; i++) std::cout << str[i][0] << str[i][1];
std::cout << std::endl;
char* d_str1;
cudaMalloc(&d_str1, 32 * sizeof(char));
char str1[32];
kernel<<<1,1>>>(d_md5Hash, d_str1);
cudaMemcpy(&str1[0], d_str1, 32 * sizeof(char), cudaMemcpyDeviceToHost);
for(int i=0; i<32; i+=2) std::cout << str1[i] << str1[i+1];
std::cout << std::endl;
return 0;
}
[Обратите внимание на весь код, написанный во время перерыва на кофе, и очень легко проверено. Используйте на свой страх и риск.