2011-10-02 8 views
30

मुझे कुछ एमडी 5 कोड मिल गए हैं जिनमें निम्न प्रोटोटाइप शामिल हैं ...सी में स्ट्रिंग का md5 हैश कैसे बनाएं?

मैं यह पता लगाने की कोशिश कर रहा हूं कि मुझे कहां रखना है, मैं कहां रखना चाहता हूं, मुझे कौन से कार्यों को कॉल करने की आवश्यकता है, और स्ट्रिंग को एक बार धोने के बाद कहां मिलना है। मैं uint32 buf [4] और uint32 बिट्स [2] संरचना में हैं के संबंध में उलझन में हूं।

struct MD5Context { 
    uint32 buf[4]; 
    uint32 bits[2]; 
    unsigned char in[64]; 
}; 

/* 
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious 
* initialization constants. 
*/ 
void MD5Init(struct MD5Context *context); 

/* 
* Update context to reflect the concatenation of another buffer full 
* of bytes. 
*/ 
void MD5Update(struct MD5Context *context, unsigned char const *buf, unsigned len); 

/* 
* Final wrapup - pad to 64-byte boundary with the bit pattern 
* 1 0* (64-bit count of bits processed, MSB-first) 
*/ 
void MD5Final(unsigned char digest[16], struct MD5Context *context); 

/* 
* The core of the MD5 algorithm, this alters an existing MD5 hash to 
* reflect the addition of 16 longwords of new data. MD5Update blocks 
* the data and converts bytes into longwords for this routine. 
*/ 
void MD5Transform(uint32 buf[4], uint32 const in[16]); 

उत्तर

35

मुझे यह विशेष पुस्तकालय नहीं पता है, लेकिन मैंने बहुत ही समान कॉल का उपयोग किया है। तो यह मेरा सबसे अच्छा अनुमान है:

unsigned char digest[16]; 
const char* string = "Hello World"; 
struct MD5Context context; 
MD5Init(&context); 
MD5Update(&context, string, strlen(string)); 
MD5Final(digest, &context); 

यह आपको हैश का पूर्णांक प्रतिनिधित्व देगा। यदि आप इसे एक स्ट्रिंग के रूप में पास करना चाहते हैं तो आप इसे हेक्स प्रस्तुति में बदल सकते हैं।

char md5string[33]; 
for(int i = 0; i < 16; ++i) 
    sprintf(&md5string[i*2], "%02x", (unsigned int)digest[i]); 
+0

अच्छा विचार, एक स्ट्रिंग के लिए हैश के रूपांतरण का प्रदर्शन। – dmckee

+0

हम्म, मुझे 'त्रुटि मिल रही है:' संदर्भ 'का भंडारण आकार ज्ञात नहीं है' मैं 'शामिल हूं ' –

+0

@SSH मुझे विश्वास नहीं है कि ओपीएस कोड openssl का उपयोग कर रहा है। –

5

ईमानदार होने के लिए, प्रोटोटाइप के साथ टिप्पणियां पर्याप्त स्पष्ट दिखाई देती हैं।

void compute_md5(char *str, unsigned char digest[16]) { 
    MD5Context ctx; 
    MD5Init(&ctx); 
    MD5Update(&ctx, str, strlen(str)); 
    MD5Final(digest, &ctx); 
} 

जहां str एक सी स्ट्रिंग आप के हैश चाहते है, और जिसके परिणामस्वरूप digest MD5 डाइजेस्ट है: कुछ इस तरह चाल करना चाहिए।

1

ऐसा लगता है कि आप

  • एक struct MD5context बनाएँ और यह एक उचित मूल्य उस हालत में पाने के लिए
  • संदर्भ के साथ कॉल MD5UpdateMD5Init को इसे पारित करने और अपने डेटा चाहिए
  • कॉल परिणामस्वरूप हैश
परिणाम प्राप्त करने के लिए

ये तीन कार्य और संरचना परिभाषा हैश एल्गोरिदम के लिए एक अच्छा सार इंटरफ़ेस बनाती है। मुझे यकीन नहीं है कि आपको उस शीर्षलेख में कोर ट्रांसफॉर्म फ़ंक्शन क्यों दिखाया गया था क्योंकि आपको शायद इसके साथ सीधे संपर्क नहीं करना चाहिए।

लेखक संरचना को एक अमूर्त प्रकार बनाकर छिपाने के लिए थोड़ा और कार्यान्वयन कर सकता था, लेकिन फिर आपको हर बार ढेर पर ढांचे को आवंटित करने के लिए मजबूर होना पड़ता था (जैसा कि अब आप इसे विरोध कर सकते हैं यदि आप चाहें तो ढेर करें)।

7

के रूप में अन्य उत्तर का उल्लेख किया है, तो निम्न कॉल हैश की गणना होगी:

MD5Context md5; 
MD5Init(&md5); 
MD5Update(&md5, data, datalen); 
MD5Final(digest, &md5); 

इसे बंटवारे है कि कई कार्यों में करने के उद्देश्य से आप बड़े डेटासेट स्ट्रीम जाने के लिए है।

उदाहरण के लिए, यदि आप 10 जीबी फ़ाइल हैशिंग कर रहे हैं और यह राम में फिट नहीं है, तो यहां आप इसे करने के बारे में जानेंगे। आप फ़ाइल को छोटे हिस्सों में पढ़ेंगे और उन पर MD5Update पर कॉल करेंगे।

MD5Context md5; 
MD5Init(&md5); 

fread(/* Read a block into data. */) 
MD5Update(&md5, data, datalen); 

fread(/* Read the next block into data. */) 
MD5Update(&md5, data, datalen); 

fread(/* Read the next block into data. */) 
MD5Update(&md5, data, datalen); 

... 

// Now finish to get the final hash value. 
MD5Final(digest, &md5); 
31

यहां एक संपूर्ण उदाहरण है:

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#if defined(__APPLE__) 
# define COMMON_DIGEST_FOR_OPENSSL 
# include <CommonCrypto/CommonDigest.h> 
# define SHA1 CC_SHA1 
#else 
# include <openssl/md5.h> 
#endif 

char *str2md5(const char *str, int length) { 
    int n; 
    MD5_CTX c; 
    unsigned char digest[16]; 
    char *out = (char*)malloc(33); 

    MD5_Init(&c); 

    while (length > 0) { 
     if (length > 512) { 
      MD5_Update(&c, str, 512); 
     } else { 
      MD5_Update(&c, str, length); 
     } 
     length -= 512; 
     str += 512; 
    } 

    MD5_Final(digest, &c); 

    for (n = 0; n < 16; ++n) { 
     snprintf(&(out[n*2]), 16*2, "%02x", (unsigned int)digest[n]); 
    } 

    return out; 
} 

    int main(int argc, char **argv) { 
     char *output = str2md5("hello", strlen("hello")); 
     printf("%s\n", output); 
     free(output); 
     return 0; 
    } 
+0

सावधान रहें, 'sprintf' में' 16 * 2' का उपयोग अमान्य है, आपको इसके बजाय '3' का उपयोग करना चाहिए (मान लीजिए कि 'आउट' काफी बड़ा है)। – Lekensteyn

+1

'MD5_Update' बाइट्स की इकाइयों में लंबाई लेता है। आप 'MD5 (str, strlen (str), digest) का भी उपयोग कर सकते हैं; क्योंकि आप पहले से ही लंबाई जानते हैं। ('MD5' अपने मैनुअल पेज के अनुसार सभी ओपनएसएसएल संस्करणों में उपलब्ध है)। – Lekensteyn

संबंधित मुद्दे