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

常用校驗演算法 C 實作總覽:SHA-1、MD5、Hash、IP Checksum、CRC32

     編輯:關於C++

1. SHA-1

OpenSSL 提供標準實作,安裝後直接連結 libcrypto:


#include 

void sha1_file(const char* path, unsigned char out[20]) {
    FILE* f = fopen(path, "rb");
    SHA_CTX ctx; SHA1_Init(&ctx);
    char buf[4096]; size_t n;
    while ((n = fread(buf, 1, sizeof(buf), f)) > 0)
        SHA1_Update(&ctx, buf, n);
    SHA1_Final(out, &ctx);
    fclose(f);
}

2. MD5 (RFC 1321)

標準實作可參考 RFC 1321 附錄或 OpenSSL MD5_Init/Update/Final。關鍵介面:


// 字串雜湊
void MDString(const char* str, unsigned char out[16]);

// 檔案雜湊
void MDFile(const char* filename, unsigned char out[16]);

注意:若自行複製 RFC 參考代碼,需移除函數前的 static 以便外部連結。

3. 通用 Hash 表雜湊


// 簡易字串雜湊 (DJB2)
unsigned long hash_djb2(const char* str) {
    unsigned long h = 5381;
    int c;
    while ((c = *str++)) h = ((h << 5) + h) + c; // h*33 + c
    return h;
}

// FNV-1a
unsigned long hash_fnv1a(const char* str) {
    unsigned long h = 2166136261u;
    while (*str) h = (h ^ *str++) * 16777619u;
    return h;
}

4. TCP/IP/UDP/ICMP Checksum (RFC 1071)


uint16_t checksum(uint16_t* buf, int len) {
    unsigned long sum = 0;
    while (len > 1) {
        sum += *buf++;
        len -= sizeof(uint16_t);
    }
    if (len) sum += *(uint8_t*)buf; // 奇數位元組補齊
    sum = (sum >> 16) + (sum & 0xFFFF);
    sum += (sum >> 16);
    return (uint16_t)~sum;
}

用途:IP 標頭、TCP/UDP 偽標頭+資料、ICMP 訊息完整性驗證。

5. CRC32 (IEEE 802.3 / Ethernet / ZIP / PNG)


// 查表法 (需預先產生 crc32table[256])
void crc32_update(const unsigned char* data, size_t len, uint32_t* crc) {
    for (size_t i = 0; i < len; i++)
        *crc = (*crc >> 8) ^ crc32table[(data[i] ^ *crc) & 0xFF];
}

int file_crc32(const char* filename, uint32_t* out_crc) {
    FILE* fp = fopen(filename, "rb");
    if (!fp) return -1;
    uint32_t crc = 0xFFFFFFFF;
    unsigned char buf[8192];
    size_t n;
    while ((n = fread(buf, 1, sizeof(buf), fp)) > 0)
        crc32_update(buf, n, &crc);
    fclose(fp);
    *out_crc = ~crc;
    return 0;
}

CRC32 查表產生 (多項式 0xEDB88320)


uint32_t crc32table[256];
void gen_crc32_table() {
    for (int i = 0; i < 256; i++) {
        uint32_t c = i;
        for (int j = 0; j < 8; j++)
            c = (c & 1) ? (0xEDB88320 ^ (c >> 1)) : (c >> 1);
        crc32table[i] = c;
    }
}

效能與選型建議

演算法速度安全性典型用途
CRC32極快 (查表)無 (非加密)檔案完整性、網路封包、存儲錯誤偵測
IP Checksum極快無IP/TCP/UDP/ICMP 標頭驗證
MD5快已破解 (碰撞)非安全性完整性檢查、舊系統相容
SHA-1中理論弱化Git 物件識別、TLS 簽章 (逐步淘汰)
SHA-256中強現代密碼應用、區塊鏈、數位簽章

現代最佳實務

  • 新專案優先使用 SHA-256 或 SHA-3 (OpenSSL EVP_Digest 介面)。
  • 檔案校驗工具建議支援多種演算法並行輸出。
  • 網路協定層 Checksum 由作業系統核心或網卡卸載,應用層鮮少手工計算。
  • CRC32 仍是嵌入式、儲存系統、即時傳輸的首選輕量校驗。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved