2016-01-23 91 views
3

我希望比較存儲在u8 [32]中的SHA-256哈希(在內核空間中計算後)與用戶作爲字符串傳遞的64個字符串進行比較。如何將十六進制字符轉換爲4位二進制表示?

例如, :用戶將一個SHA-256哈希「49454bcda10e0dd4543cfa39da9615a19950570129420f956352a58780550839」作爲char *,這將需要64個字節。但是這必須與內核空間中的散列進行比較,該散列表示爲u8散列[32]。

int i; 
u8 hash[32]; 

for(i=0; i<32; i++) 
    printk(KERN_CONT "%hhx ", hash[i]); 

輸出:: 「49 45 4B CD A1 0E 0D D4 54 3C FA 39 DA 96 15 A1 99 50 57 01

內核內的散列被適當地通過下面的代碼印在ASCII 29 42 0f 95 63 52 a5 87 80 55 08 39「

由於完整散列存儲在32個字節中,並且打印爲每個u8空間2個字符組的64個字符,我假設當前一個u8塊存儲信息值2個字符,即00101111打印爲2f。

有沒有辦法在32字節中存儲64字節的字符串,以便它可以進行比較?

回答

4

下面是如何使用scanf做轉換:

char *shaStr = "49454bcda10e0dd4543cfa39da9615a19950570129420f956352a58780550839"; 
uint8_t sha[32]; 
for (int i = 0 ; i != 32 ; i++) { 
    sscanf(shaStr+2*i, "%2" SCNx8, &sha[i]); 
    printf("%02x ", sha[i]); 
} 

這裏的做法是與"%2" SCNx8格式說明,這意味着「二十六進制字符轉換爲uint8_t」反覆調用sscanf。該位置由循環迭代的指標確定,即shaStr+2*i

Demo.

+0

印刷,你可能想'%02x',而不是'%hhx'。 – fuz

+0

@FUZxxl你說得對。我複製了OP的格式說明符。 – dasblinkenlight

1

字符通常存儲在ASCII中,因此首先查看ASCII chart。這會告訴你一個字符如'a'和數字97之間的關係。

你會注意到所有的數字都緊挨着。這就是爲什麼你經常看到人們做c-'0'c-48,因爲它會將ASCII編碼的數字轉換爲可以使用的數字。

但是你會注意到字母和數字相距很遠,這樣稍微不方便。如果按位排列它們,您可能會注意到一種模式:位6(& 64)設置爲字母,但未設置數字。觀察到,轉換十六進制ASCII字符爲數字很簡單:

int h2i(char c){return (9*!!(c&64))+(c&15);} 

一旦轉換單個字符,將字符串轉換也很簡單:

void hs(char*d,char*s){while(*s){*d=(h2i(*s)*16)+h2i(s[1]);s+=2;++d;}} 

添加嵌入式非十六進制字符的支持(像空白)是一個有用的練習,你可以做的就是說服自己你明白髮生了什麼。

相關問題