首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言實現文件指定區域 MD5 計算:從源碼到 Makefile 完整教程

     編輯:關於C語言

基於 OpenSSL 兼容算法的文件片段 MD5 計算實戰

本文提供一個輕量級、可移植的 MD5 實現(基於 Solar Designer 公共域代碼),演示如何讀取文件指定偏移區間並計算其 MD5 摘要,包含完整源碼、測試程序與 Makefile。

一、MD5 核心實現 (md5.h/md5.c)

特點:無版權限制、無 32 位整數依賴、無大小端配置、API 與 OpenSSL 兼容 (MD5_Init/Update/Final)。

// md5.h
typedef struct {
    MD5_u32plus lo, hi;      // 位計數器
    MD5_u32plus a, b, c, d;  // 狀態變量
    unsigned char buffer[64]; // 數據緩衝區
    MD5_u32plus block[16];    // 16 個 32 位字
} MD5_CTX;

void MD5_Init(MD5_CTX *ctx);
void MD5_Update(MD5_CTX *ctx, const void *data, unsigned long size);
void MD5_Final(unsigned char *result, MD5_CTX *ctx);

md5.c 實現了 RFC 1321 四輪變換(F/G/H/I 函數),採用 STEP 宏優化,支持任意長度數據流式處理。

二、測試程序:指定區間計算 MD5

// test.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "md5.h"

unsigned char *getMD5InRange(const char *filename, long start, long end) {
    FILE *fp = fopen(filename, "rb");  // 二進制模式關鍵!
    if (!fp) return NULL;
    fseek(fp, start, SEEK_SET);
    long len = end - start + 1;
    char *buf = malloc(len + 1);
    fread(buf, 1, len, fp);
    buf[len] = '\0';
    fclose(fp);

    unsigned char *digest = malloc(16);
    MD5_CTX ctx;
    MD5_Init(&ctx);
    MD5_Update(&ctx, buf, len);  // 使用 len 而非 strlen,支持二進制數據
    MD5_Final(digest, &ctx);
    free(buf);
    return digest;
}

int main(void) {
    int st, ed;
    while (scanf("%d %d", &st, &ed) == 2) {
        unsigned char *md5 = getMD5InRange("aaa.txt", st, ed);
        if (md5) {
            for (int i = 0; i < 16; ++i) printf("%02x", md5[i]);
            printf("\n");
            free(md5);
        }
    }
    return 0;
}

三、關鍵技術點解析

四、Makefile 構建

test: test.o md5.o
	cc -o test test.o md5.o

test.o: test.c md5.h
	cc -c test.c

md5.o: md5.c md5.h
	cc -c md5.c

clean:
	rm -f *.o test

五、測試驗證

文件 aaa.txt 內容:

shanghaisndacompanygrandcloudwww.grandcloud.com

運行 ./test 輸入偏移量,如 0 10,輸出對應 MD5。可與 md5sum 命令驗證全文件摘要一致性。

六、避坑指南

  • ❌ 文本模式讀取二進制文件 → MD5 錯誤(Windows)。
  • ❌ strlen 計算二進制長度 → 遇 \0 截斷。
  • ❌ 忽略 fseek 返回值 → 偏移失敗未檢測。
  • ✅ 生產環境優先用 OpenSSL EVP_Digest 或系統 libmd,經過優化且經過安全審計。

這個輕量級 MD5 實現適合嵌入式、教學、無依賴環境;掌握流式計算、二進制讀取、偏移定位技巧,可擴展至大文件分片校驗、斷點續傳完整性驗證等場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
點說明
二進制模式 "rb"Windows 下文本模式會轉換換行符,導致 MD5 不匹配;Unix/Linux 無影響但建議統一用 rb。
MD5_Update 長度參數必須傳實際讀取字節數 len,不可用 strlen(buf)(二進制數據可能含 \0)。
緩衝區分配malloc(len + 1) 並手動添加 \0 便於調試打印,實際計算不依賴結束符。
摘要輸出格式%02x 確保每字節兩位十六進制,共 32 字符。