Конвертировать HEX в печатную строку / символ
Я использую CNG для генерации хэша. Результатом вызова BCryptFinishHash является MD5 входа в шестнадцатеричной форме. Пример:
char *outHash = "\x02\x34\x75\01..."
Я хочу преобразовать его в строку для печати: 02347501...
Как я могу это сделать?
6 ответов
Мы можем использовать 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);
}
}
}
Чтобы закодировать массив байтов в шестнадцатеричном виде и записать закодированные данные в 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;
}
Обратите внимание, что вы должны знать длину байтового массива. Не безопасно рассматривать его как завершенную NUL строку "C", потому что двоичные данные могут содержать внутренние нулевые байты. Чтобы узнать длину хеша, сгенерированного CNG, вызовите BCryptGetProperty, чтобы получить BCRYPT_HASH_LENGTH
имущество.
Вы можете напечатать это так:
for(const char *wsk=outHash; *wsk; ++wsk){
printf("%02hhx", *wsk);
}
Редактируйте, основываясь на том, что cstring может иметь числа 0x00.
С
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]);
}
Обведите символы и выведите числовое значение (в шестнадцатеричном формате).
#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";
}
Я работаю над оболочкой 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"));
Если вам нужно простое однократное решение, это полезный инструмент: https://codebeautify.org/hex-string-converter
Однако, если вы хотите сделать это в самом коде, я нашел это в более ранней ветке (AKA, это не моя работа, а работа с @ 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; }