2016-06-08 356 views
1

我正在嘗試使用微控制器將磁盤格式化爲exFAT。我的問題是,我需要計算校驗和,使用VBR(Volume Boot Region)的扇區1到11中的字節將其存儲到扇區12中,但是結果不正確。當校驗和不正確時,Windows或任何其他識別exFAT的操作系統都無法使用該磁盤,因爲校驗和已驗證,並且如果錯誤發生致命錯誤。exFAT校驗和的計算

下面是計算32位校驗功能:

uint32_t BootChecksum(char * data, long bytes){ 
    uint32_t checksum = 0; 
    for (uint32_t i = 0 ; i < bytes ; i++){ 
     if (i == 106 || i == 107 || i == 112) 
      continue; 
     checksum = ((checksum << 31) | (checksum >> 1)) + (uint32_t) data[i]; 
     if(checksum == 0xF1924082){ 
      printf("%02X | i = %d", checksum, i); 
     } 
    } 
    return checksum; 
} 

從我已經能夠閱讀,功能是正確的,所以我的猜測是,我使用的數據是不正確的。我只需要11個扇區,每個扇區512個字節,結果是一個5632字節的數組。

我已經使用了類似的函數來計算條目集(16位校驗和)的校驗和,結果是正確的,它確實是數據,但我不明白我在那裏失蹤了什麼!

任何知道exFAT的人都能幫助我嗎?謝謝!

回答

1

我懷疑這是一個運算符優先級的問題。

this page我看到了CRC的定義,其中checksum以這種方式

checksum = (checksum<<31) | (checksum>> 1) + data[i]; 

也就是說,如果我沒有錯的修改,相當於

checksum = (checksum<<31) | ((checksum>> 1) + data[i]); 

,因爲(如果我記得很清楚)加號運算符(+)比位或運算符(|)具有更高的優先級。

相反,你的代碼是

checksum = ((checksum << 31) | (checksum >> 1)) + (uint32_t) data[i]; 

這是一個總不同的代碼,因爲你先申請按位或與旁邊的加。

我想可以用

checksum = (checksum << 31) | ((checksum >> 1) + (uint32_t) data[i]); 

PS工作:對不起,我的英語不好

---編輯2016年6月9日---

另一個問題應該是簽名爲data

您將data定義爲char的指針; ntfs.com將data定義爲const unsigned char的數組。

指針/數組差異不是問題; const部分不重要(但我建議您將data定義爲const);如果char使用負值而不是unsigned char進行簽名,則問題(我想)是轉換爲uint32_tchar

舉例:假設data[i]的值爲-1;與(uint32_t) data[i],如果我記得不錯,第一個data[i]轉換爲int(-1)和下一個在uint32_t(-1)。所以,你得到4294967295

如果您data[i]unsigned char,而不是-1 data[i]值爲255;所以(uint32_t) data[i]先轉換255 int(255),也就是255,旁邊uint32_t(255),仍然存在255

簡單地說,我的建議是:改變

checksum = (checksum << 31) | ((checksum >> 1) + (uint32_t) data[i]); 

checksum = (checksum << 31) | ((checksum >> 1) + (uint32_t) (unsigned char) data[i]); 

或者乾脆

checksum = (checksum << 31) | ((checksum >> 1) + (unsigned char) data[i]); 
+0

你確實是對的,我試着用你的圓括號沒有任何括號,我得到了相同的結果,因此似乎我誤解了操作員的優先權!但是,結果仍然不正確。我得到0x95672D57,而我應該有0xF1924082。謝謝你的幫助! –

+1

@ArthurPenguin - 解決了一個問題,讓我們看看我們是否可以解決另一個問題;我編輯了我的anser,提示您的代碼中有另一個更改來解決簽名問題 – max66

+0

謝謝,絕對解決了它! –