簡體   English   中英

將HEX轉換為可打印的字符串/ char

[英]Convert HEX to printable string/char

我正在使用CNG生成哈希。 BCryptFinishHash調用的結果是十六進制形式的輸入的MD5。 例:

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

我想將其轉換為可打印的字符串:02347501 ...

我怎樣才能做到這一點?

要以十六進制編碼字節數組並將編碼數據寫入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屬性。

我們可以在這里使用CryptBinaryToStringCRYPT_STRING_HEXASCIICRYPT_STRING_HEXCRYPT_STRING_HEXRAWCRYPT_STRING_HEX | CRYPT_STRING_NOCRLF CRYPT_STRING_HEX | CRYPT_STRING_NOCRLFCRYPT_STRING_HEXRAW | 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);
        }
    }
}

如果您需要一個簡單的一次性解決方案,這是一個有用的工具: 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; } 

你可以像這樣打印:

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]);
}

循環遍歷字符並打印數值(以十六進制表示)。

#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";
}

我正在研究我在項目中使用的Windows Crypto API和CNG的C ++包裝器。 我計划將它全部移動到github但是現在它只是一項正在進行的工作,但你會發現它對於像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" */

您也可以使用位於Hash名稱空間中的MD5包裝器,就像這樣。 (如果您沒有使用大量數據)

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

using namespace m4x1m1l14n;

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM