2013-11-21 36 views
0

有人能解釋一下這段代碼在做什麼嗎?我必須解釋這段代碼並將其用作校驗和代碼,但我不確定它是否絕對正確。特別是溢出如何工作以及*cp, const char* cpsum & 0xFFFF是什麼意思?其基本思想是將用戶輸入的字符串作爲字符串,一次將其轉換爲二進制格式的16位數據。然後將所有的多個16位相加(二進制)並得到16位和。如果在添加中有任何溢出位,則將其添加到最終總和的lsb。然後採取補充結果。C++中的校驗碼

這段代碼與上述做法有多接近?

unsigned int packet::calculateChecksum() 

{ 
unsigned int c = 0; 
int i; 
string j; 
int k; 
cout<< "enter a message" << message; 
getline(cin, message) ; // Some string. 
//std::string message = 
std::vector<uint16_t> bitvec; 
const char* cp = message.c_str()+1; 
while (*cp) { 
    uint16_t bits = *(cp-1)>>8 + *(cp); 
    bitvec.push_back(bits); 
    cp += 2; 
} 

uint32_t sum=0; 
uint16_t overflow=0; 
uint32_t finalsum =0; 

// Compute the sum. Let overflows accumulate in upper 16 bits. 
for(auto j = bitvec.begin(); j != bitvec.end(); ++j) 
    sum += *j; 

// Now fold the overflows into the lower 16 bits. Loop until no overflows. 
do { 
    sum = (sum & 0xFFFF) + (sum >> 16); 
    } while (sum > 0xFFFF); 

// Return the 1s complement sum in finalsum 
finalsum = 0xFFFF & sum; 

    //cout<< "the finalsum is" << c; 
     c = finalsum; 
     return c; 

    } 
+1

至少補碼需要是0xFFFF^sum或0xFFFF - sum:循環while(* cp)'是錯誤的,因爲它不能真正處理例如字符串「a」。 (如果在ascii zero終止之後有什麼垃圾怎麼辦? –

+0

是否有反對使用像SHA這樣的標準哈希碼的原因(http://en.wikipedia.org/wiki/Secure_Hash_Algorithm)? –

+0

BTW。這種Q屬於codereview。 –

回答

0

我看到在代碼幾個問題:

  1. cp是指向零結束字符數組保持輸入消息。 while(*cp)會有問題,因爲在while循環體cp中增加2!因此,跳過字符數組的末尾\0(例如,輸入消息具有2個字符)並導致分段錯誤相當容易。
  2. *(cp)*(cp-1)獲取輸入消息中的兩個相鄰字符(字節)。但爲什麼這兩個字節的單詞是由*(cp-1)>>8 + *(cp)組成的?我認爲通過*(cp-1)<<8 + *(cp)形成16位字是有意義的,即前面的字符位於高位字節,而後面的字符位於16位字的低位字節。

要回答你的問題sum & 0xFFFF只是意味着計算一個數字,其中高16位是零,低16位是相同的總和。 0xFFFF是一個位掩碼。

有趣的是,即使上面的代碼可能沒有按照要求提供確切的東西,只要發送方和接收方使用相同的一段不正確的代碼,您的校驗和創建和驗證就會通過兩端是一致的:)

+0

感謝您的評論真的有幫助!我wana知道最後一件事...... uint總結...這是否意味着我的總和是一個32位的無符號整數:當它說uint32?shoudlnt它是16然後呢? – user899714

+0

在這裏採取的補碼是什麼?和位掩碼做什麼? – user899714

+0

@ user899714我不認爲有什麼與你在代碼中計算補碼有關的任何東西osted。 你可以谷歌如何計算補碼,就像[這裏](http://courses.cs.vt.edu/~csonline/NumberSystems/Lessons/OnesComplement/index.html)。 uint_32t是總和(無符號32位整數)的類型,即32位的最高有效位(MSB)不能**被解釋爲符號位。 通過「掩蔽」,您可以獲得您感興趣的位並忽略其他位,因爲它們全都被掩碼清零。 –