日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

checksum algorithm adler32

發布時間:2024/3/24 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 checksum algorithm adler32 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在 wiki 上有比較詳細的解釋 以下大部分解釋來自 wiki 上的說明

  • 一個 adler-32 checksum 是由兩個 16bit checksum A 與 B 組合而成的 32bit 的數
  • A 初始化為 1 B 初始化為 0
  • A是需要計算的字符串中每一個字符相加的值 并且對 65521 取模
  • B是每一步中A的值相加 并且對 65521 取模
  • 65521 是 2^16 內的最大質數
  • 用途
    • adler32 checksum 在 zlib 庫中被廣泛的使用
    • 在rsync utility 中也有使用 rolling checksum

具體的偽代碼如下 D 是需要進行adler32計算的字符串(string of bytes) n 是 D 的長度

A = 1 + D1 + D2 + D3 + ... + Dn (mod 65521) B = (1 + D1) + (1 + D1 + D2) + ... + (1 + D1 + D2 + ... + Dn) (mod 65521)↓↓↓ 等價于下面 B = n * D1 + (n - 1) * D2 + (n - 2) * D3 + ... + Dn + n (mod 65521) Adler-32(D) = B * 65535 + A

wiki上給出的C實現實例如下adler32函數所示 基本和偽代碼一致

#include <iostream> using namespace std;const uint32_t MOD_ADLER = 65521;uint32_t adler32(unsigned char *data, size_t len) {uint32_t a = 1, b = 0;size_t index;for (index = 0; index < len; ++index){a = (a + data[index]) % MOD_ADLER;b = (b + a) % MOD_ADLER;}return (b << 16) | a; }int main(int argc, char *argv[]) {unsigned char *data;data = (unsigned char *)("Wikipedia");adler32(data, 9);return 1; }

在 rsync 中的checksum方法如下

/*a simple 32 bit checksum that can be upadted from either end(inspired by Mark Adler's Adler-32 checksum)*/ uint32 get_checksum1(char *buf1, int32 len) {int32 i;uint32 s1, s2;schar *buf = (schar *)buf1;s1 = s2 = 0;for (i = 0; i < (len-4); i+=4) {s2 += 4*(s1 + buf[i]) + 3*buf[i+1] + 2*buf[i+2] + buf[i+3] +10*CHAR_OFFSET;s1 += (buf[i+0] + buf[i+1] + buf[i+2] + buf[i+3] + 4*CHAR_OFFSET);}for (; i < len; i++) {s1 += (buf[i]+CHAR_OFFSET); s2 += s1;}return (s1 & 0xffff) + (s2 << 16); }// 其中 schar 和 CHAR_OFFSET 的定義在 rsync.h 中如下 #ifdef SIGNED_CHAR_OK #define schar signed char #else #define schar char #endif/* a non-zero CHAR_OFFSET makes the rolling sum stronger, but isincompatible with older versions :-( */ #define CHAR_OFFSET 0

閱讀代碼發現 只有 A 的初始值從 1 變成了 0 不一樣
根據定義稍微簡化一下如下 并加以測試

uint32_t get_checksum(const char *buf, uint32_t len) {uint32_t i;uint32_t s1, s2;s1 = s2 = 0;for (i = 0; i < (len - 4); i += 4){s2 += 4 * (s1 + buf[i]) + 3 * buf[i + 1] + 2 * buf[i + 2] + buf[i + 3];s1 += (buf[i + 0] + buf[i + 1] + buf[i + 2] + buf[i + 3]);}for (; i < len; i++){s1 += buf[i];s2 += s1;}return (s1 & 0xffff) + (s2 << 16); }int main(int argc, char *argv[]) {unsigned char *data;data = (unsigned char *)("Wikipedia");adler32(data, 9);get_checksum("Wikipedia", 9);return 1; }

由于初始化是 A 初始化為 0 所以計算出來的 A B 兩個值有差異 以上面的測試來說 A 相差 1 B 相差 9
如果初始化為 s1=1,s2=0 那么結果將完全一致

總結

以上是生活随笔為你收集整理的checksum algorithm adler32的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。