C에서 문자열의 md5 해시를 생성하는 방법은?
다음과 같은 시제품으로 구성된 md5 코드를 찾았습니다.
해시하고 싶은 문자열을 어디에 넣어야 하는지, 어떤 기능을 호출해야 하는지, 해시가 끝나면 문자열을 어디서 찾을 수 있는지 등을 알아보려고 했습니다.uint32 buf[4]와 uint32 bits[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]);
저는 이 도서관을 잘 모르지만, 아주 비슷한 전화를 이용한 적이 있습니다.제 추측으로는 이렇습니다.
unsigned char digest[16];
const char* string = "Hello World";
struct MD5Context context;
MD5Init(&context);
MD5Update(&context, string, strlen(string));
MD5Final(digest, &context);
그러면 해시의 정수 표현이 반환됩니다.문자열로 전달하려면 16진수 표현으로 변환할 수 있습니다.
char md5string[33];
for(int i = 0; i < 16; ++i)
sprintf(&md5string[i*2], "%02x", (unsigned int)digest[i]);
완전한 예는 다음과 같습니다.
#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;
}
다른 답변들이 언급한 것처럼, 다음 호출들은 해시를 계산할 것입니다.
MD5Context md5;
MD5Init(&md5);
MD5Update(&md5, data, datalen);
MD5Final(digest, &md5);
이렇게 많은 기능으로 분할하는 목적은 대규모 데이터셋을 스트리밍할 수 있도록 하는 것입니다.
예를 들어, 10GB 파일을 해시할 때 램에 맞지 않는 경우 다음과 같이 수행할 수 있습니다.파일을 더 작은 청크로 읽고 호출합니다.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);
솔직히 말하면 시제품에 첨부된 코멘트는 충분히 분명해 보입니다.이와 같은 것이 효과가 있을 것입니다.
void compute_md5(char *str, unsigned char digest[16]) {
MD5Context ctx;
MD5Init(&ctx);
MD5Update(&ctx, str, strlen(str));
MD5Final(digest, &ctx);
}
어디에str
는 해시를 원하는 C 문자열이며,digest
결과 MD5 다이제스트입니다.
당신이 해야 할 것 처럼 보일 것입니다.
- 만들기
struct MD5context
그것을 에 전합니다.MD5Init
그것을 적절한 출발 상태로 만들기 위해 - 불러
MD5Update
사용자의 데이터와 함께 - 불러
MD5Final
결과적인 해시를 얻다
이 세 가지 함수와 구조 정의는 해시 알고리즘에 대한 멋진 추상 인터페이스를 만듭니다.저는 당신이 왜 그 헤더에 핵심 변환 기능을 표시했는지 잘 모르겠습니다. 아마도 당신은 그것과 직접적으로 상호작용해서는 안 될 것이기 때문입니다.
작성자는 구조를 추상적인 유형으로 만들어서 구현 숨김을 조금 더 할 수 있었지만, 그때마다 구조를 스택에 배치할 수밖에 없었을 것입니다(지금과는 반대로 원하는 경우 스택에 배치할 수 있습니다).
기존의 답변은 모두 사용하지 않는 답변을 사용합니다. MD5Init()
,MD5Update()
,그리고.MD5Final()
.
대신 사용EVP_DigestInit_ex()
,EVP_DigestUpdate()
,그리고.EVP_DigestFinal_ex()
,예.
// example.c
//
// gcc example.c -lssl -lcrypto -o example
#include <openssl/evp.h>
#include <stdio.h>
#include <string.h>
void bytes2md5(const char *data, int len, char *md5buf) {
// Based on https://www.openssl.org/docs/manmaster/man3/EVP_DigestUpdate.html
EVP_MD_CTX *mdctx = EVP_MD_CTX_new();
const EVP_MD *md = EVP_md5();
unsigned char md_value[EVP_MAX_MD_SIZE];
unsigned int md_len, i;
EVP_DigestInit_ex(mdctx, md, NULL);
EVP_DigestUpdate(mdctx, data, len);
EVP_DigestFinal_ex(mdctx, md_value, &md_len);
EVP_MD_CTX_free(mdctx);
for (i = 0; i < md_len; i++) {
snprintf(&(md5buf[i * 2]), 16 * 2, "%02x", md_value[i]);
}
}
int main(void) {
const char *hello = "hello";
char md5[33]; // 32 characters + null terminator
bytes2md5(hello, strlen(hello), md5);
printf("%s\n", md5);
}
언급URL : https://stackoverflow.com/questions/7627723/how-to-create-a-md5-hash-of-a-string-in-c
'it-source' 카테고리의 다른 글
라인 아이템 우커머스 주문 받기 (0) | 2023.10.13 |
---|---|
C에서 메모리를 동적으로 할당해야 하는 이유는 무엇입니까? (0) | 2023.10.13 |
시스템 ()이(가) 비활성화되었습니다 오류 메시지 (0) | 2023.10.13 |
'Oracle'의 형식 이니셜라이저입니다.데이터 액세스.고객.Oracle Connection'이(가) 예외를 던졌습니다. (0) | 2023.10.13 |
라디오 그룹에서 선택한 라디오를 값으로 설정합니다. (0) | 2023.10.13 |