leveldb源碼學(xué)習(xí)--crc32

CRC原理

基本概念

CRC(Cyclic Redundancy Check)中文名是循環(huán)冗余校驗,其計算簡單,被廣泛應(yīng)用于數(shù)據(jù)校驗,具有很強的檢錯能力。

數(shù)學(xué)原理

CRC算法是已GF(2)多項式為數(shù)學(xué)基礎(chǔ)的,這個不是很難理解,說白了其實就是在玩異或運算。這篇博文對其中的數(shù)學(xué)講的很通俗易懂,推薦大家可以參考下。

源碼實現(xiàn)

leveldb中對于crc32實現(xiàn)還是非常簡單的,核心在于一個Extend()函數(shù)。

uint32_t Extend(uint32_t crc, const char* buf, size_t size) {
  const uint8_t *p = reinterpret_cast<const uint8_t *>(buf);
  const uint8_t *e = p + size;
  uint32_t l = crc ^ 0xffffffffu;

#define STEP1 do {                              \
    int c = (l & 0xff) ^ *p++;                  \
    l = table0_[c] ^ (l >> 8);                  \
} while (0)
#define STEP4 do {                              \
    uint32_t c = l ^ LE_LOAD32(p);              \
    p += 4;                                     \
    l = table3_[c & 0xff] ^                     \
        table2_[(c >> 8) & 0xff] ^              \
        table1_[(c >> 16) & 0xff] ^             \
        table0_[c >> 24];                       \
} while (0)

  // Point x at first 4-byte aligned byte in string.  This might be
  // just past the end of the string.
  const uintptr_t pval = reinterpret_cast<uintptr_t>(p);
  const uint8_t* x = reinterpret_cast<const uint8_t*>(((pval + 3) >> 2) << 2);
  if (x <= e) {
    // Process bytes until finished or p is 4-byte aligned
    while (p != x) {
      STEP1;
    }
  }
  // Process bytes 16 at a time
  while ((e-p) >= 16) {
    STEP4; STEP4; STEP4; STEP4;
  }
  // Process bytes 4 at a time
  while ((e-p) >= 4) {
    STEP4;
  }
  // Process the last few bytes
  while (p != e) {
    STEP1;
  }
#undef STEP4
#undef STEP1
  return l ^ 0xffffffffu;
}

實現(xiàn)的比較簡潔,關(guān)鍵處也有代碼注釋,如果你明白了CRC的原理,相信讀懂這份代碼應(yīng)該沒有什么困難。細(xì)讀這份代碼時還是學(xué)習(xí)了一個新技巧

#define STEP1 do {                              \
    int c = (l & 0xff) ^ *p++;                  \
    l = table0_[c] ^ (l >> 8);                  \
} while (0)
#define STEP4 do {                              \
    uint32_t c = l ^ LE_LOAD32(p);              \
    p += 4;                                     \
    l = table3_[c & 0xff] ^                     \
        table2_[(c >> 8) & 0xff] ^              \
        table1_[(c >> 16) & 0xff] ^             \
        table0_[c >> 24];                       \
} while (0)

在宏定義的時候為何給他套上一個do{...}while(0),剛開始非常疑惑,這層嵌套的價值在何處,按理來說在這份代碼中,將這種宏定義直接改成這樣就行

#define STEP1 int c = (l & 0xff) ^ *p++;               \
    l = table0_[c] ^ (l >> 8)                          \

#define STEP4 uint32_t c = l ^ LE_LOAD32(p);              \
    p += 4;                                                 \
    l = table3_[c & 0xff] ^                     \
        table2_[(c >> 8) & 0xff] ^              \
        table1_[(c >> 16) & 0xff] ^             \
        table0_[c >> 24]                       \

的確這樣可以(針對crc32c.cc)中而言。
但是考慮這樣的宏定義在下面這種情況的結(jié)果

#define FOO(x) foo(x); bar(x)

if (condition)
    FOO(x);
else // syntax error here
    ...;

即便你加上大括號,也無濟于事,like this:

#define FOO(x) { foo(x); bar(x); }

除非你改寫語句成下面這種語句

if (condition)
    FOO(x)
else
    ...

沒有分號結(jié)尾,你能忍?作為一個忠實的CPP黨是不能忍的。所以如果你套上一個do{...}while(0),看起來就舒服多了。==這篇好像和crc32沒太多關(guān)系了....不管了反正這些東西都是在看crc32上學(xué)到的==

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,094評論 25 709
  • 發(fā)現(xiàn)寫博客想寫明白也是一件不容易的事情。 這次拿YYKIt 源碼 分析分析。希望這次能寫的更好些。 YYKit 系...
    充滿活力的早晨閱讀 6,810評論 4 16
  • 前言 CRC校驗(循環(huán)冗余校驗)是數(shù)據(jù)通訊中最常采用的校驗方式。在嵌入式軟件開發(fā)中,經(jīng)常要用到CRC 算法對各種數(shù)...
    Otis4631閱讀 1,856評論 0 3
  • 投資的定義 買入之初,就想等著有人從自己手中以更高的價格買走。 投機的定義 經(jīng)過詳盡分析之后,確保買入的本金安全且...
    逐日的我閱讀 448評論 0 2
  • 一、刻意練習(xí),練什么? 1.錯誤的練習(xí) ①以賽代練。比賽經(jīng)驗是提高了,但基本功沒有提高。 ②倒背如流。炫技式的練習(xí)...
    安定的貓閱讀 357評論 0 1

友情鏈接更多精彩內(nèi)容