Конвертировать HEX в печатную строку / символ - PullRequest
0 голосов
/ 25 января 2019

Я использую CNG для генерации хэша. Результатом вызова BCryptFinishHash является MD5 входа в шестнадцатеричной форме. Пример:

char *outHash = "\x02\x34\x75\01..."

Я хочу преобразовать его в строку для печати: 02347501 ...

Как я могу это сделать?

Ответы [ 6 ]

0 голосов
/ 25 января 2019

Я работаю над оболочкой C ++ для Windows Crypto API и CNG, которую я использую в своих проектах. Я планирую перенести все это на github, но пока это просто работа, но вы можете найти ее полезной для основ Crypto, таких как кодирование / декодирование HEX / Base64 и т. Д.

https://github.com/m4x1m1l14n/Crypto

Вы можете использовать метод Crypto :: Hex :: Encode () для достижения желаемого.

#include <Crypto\Hex.hpp>
#include <Crypto\Random.hpp>

using namespace m4x1m1l14n;

char arr[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0x99, 0x00 };

encoded = Crypto::Hex::Encode(arr, sizeof(arr));

/* encoded = "aabbccdd9900" */

Также вы можете использовать обертку для MD5, которая находится в пространстве имен Hash, вот так. (Если вы не используете большой объем данных)

#include <Crypto\Hex.hpp>
#include <Crypto\Hash.hpp>

using namespace m4x1m1l14n;

encoded = Crypto::Hex::Encode(Crypto::Hash::MD5("Whatever you want to hash"));

0 голосов
/ 25 января 2019

Обведите символы и выведите числовое значение (в шестнадцатеричном формате).

#include <iostream>
#include <iomanip>

int main()
{
    char*  outHash = "\x02\x34\x75\x01\x23\xff";  // Get from your Hash function.
    int    sizeOfHash = 6;                        // Use appropriate size for BCryptFinishHash()


    // Set up the characteristics of the stream.
    // setw(2):       Each printed object will use a min width of 2
    // setfill('0'):  If the object is less than 2 char then fill the space with '0'
    // hex:           Print numbers in hex.
    std::cout << std::setw(2) << std::setfill('0') << std::hex;

    // Create a view of the object.
    // Makes it simpler to loop over.
    std::string_view view(outHash, sizeOfHash);

    // Loop over the string.
    for(unsigned char val: view) {
        // Convert to `unsigned char` to make sure you don't print
        // negative numbers. Then convert from there to `int` so that
        // the `std::hex will kick in and convert to hex value.
        std::cout << static_cast<int>(val);
    }   
    std::cout << "\n";
}
0 голосов
/ 25 января 2019

Чтобы закодировать байтовый массив в шестнадцатеричном виде и записать закодированные данные в std::string, сделайте следующее:

static inline char
hex_digit(unsigned int n)
{
    if (n < 10) return '0' + n;
    if (n < 16) return 'a' + (n - 10);
    abort();
}

std::string
encode_bytes(const unsigned char *bytes, size_t len)
{
    std::string rv;
    rv.reserve(len * 2);
    for (size_t i = 0; i < len; i++) {
        rv.push_back(hex_digit((bytes[i] & 0xF0) >> 4));
        rv.push_back(hex_digit((bytes[i] & 0x0F) >> 0));
    }
    return rv;
}

Обратите внимание, что вы должны знать длину байтового массива. Не безопасно рассматривать его как «C-строку» с NUL-концевым символом, потому что двоичные данные могут содержать внутренние нулевые байты. Чтобы узнать длину хэша, сгенерированного CNG, вызовите BCryptGetProperty , чтобы получить свойство BCRYPT_HASH_LENGTH.

0 голосов
/ 25 января 2019

мы можем использовать CryptBinaryToString здесь с CRYPT_STRING_HEXASCII или CRYPT_STRING_HEX или CRYPT_STRING_HEXRAW или CRYPT_STRING_HEX | CRYPT_STRING_NOCRLF или CRYPT_STRING_HEXRAW | CRYPT_STRING_NOCRLF в зависимости от того, как вы хотите отформатировать строку.например

void print(PUCHAR pbHash, ULONG cbHash, DWORD dwFlags = CRYPT_STRING_HEXRAW | CRYPT_STRING_NOCRLF)
{
    ULONG cch = 0;
    if (CryptBinaryToStringW(pbHash, cbHash, dwFlags, 0, &cch))
    {
        if (PWSTR sz = (PWSTR)_malloca(cch * sizeof(WCHAR)))
        {
            if (CryptBinaryToStringW(pbHash, cbHash, dwFlags, sz, &cch))
            {
                DbgPrint("%S\n", sz);
            }
            _freea(sz);
        }
    }
}
0 голосов
/ 25 января 2019

Вы можете напечатать это так:

for(const char *wsk=outHash; *wsk; ++wsk){
    printf("%02hhx", *wsk);
}

Редактирование на основе того, что cstring может иметь числа 0x00.
C

const char outHash[] = "\x02\x34\x75";
const int size = sizeof(outHash)/sizeof(char) - 1;
for(int i = 0; i < size; ++i){
    printf("%02hhx", outHash [i]);
}

C ++

std::string outHash = "\x02\x34\x75";
for(int i = 0; i < outHash.size(); ++i) {
    printf("%02hhx", outHash [i]);
}
0 голосов
/ 25 января 2019

Если вам нужно простое одноразовое решение, это полезный инструмент: https://codebeautify.org/hex-string-converter

Однако, если вы хотите сделать это в самом коде, я обнаружил это из более ранней темы (AKA, это не моя работа, а @ @ 1004 * KEINE LUST из здесь )

int main(void)
{
unsigned char readingreg[4];
readingreg[0] = 0x4a;
readingreg[1] = 0xaa;
readingreg[2] = 0xaa;
readingreg[3] = 0xa0;
char temp[4];

sprintf(temp, "%x", readingreg[0]);
printf("This is element 0: %s\n", temp);
return 0;
}
...