...我們得到了相同的校驗...是這是預期的?
是的,因爲它是可能的。校驗和是16位(並且從不出現511個組合):0x..FF
,0xFF..
),所以3個字符串24位肯定會發生衝突。 Pigeonhole principle
不應該使用Fletcher16校驗和來計算塊的順序嗎?
它的確如此。只是該算法容易與選擇的相似輸入相沖突。也參見Hamming distance
順便說一句,原始算法給出不同的結果,如果該長度或大小(也查詢空字符)用於的字符串。另外,4個輸入字符串給出了一對不同的結果。
printf("%x\n", fletcher16("BCA",3)); // 8ec6
printf("%x\n", fletcher16("CAB",3)); // 8ec6 same
printf("%x\n", fletcher16("BAC",3)); // 8cc6
printf("%x\n", fletcher16("ACB",3)); // 8cc6 same
printf("%x\n", fletcher16("BCA",4)); // 55c6
printf("%x\n", fletcher16("CAB",4)); // 55c6 same
printf("%x\n", fletcher16("BAC",4)); // 53c6
printf("%x\n", fletcher16("ACB",4)); // 53c6 same
OP商建議的改進削弱了校驗和也可作爲由-ING或在索引中,其中在每個階段忽略選擇位。建議改變或添加。
小尼特:
// return (sum2 << 8) | sum1;
return (1u*sum2 << 8) | sum1;
這種變化是不是determental所有int/unsigned
尺寸又避免了實現定義的行爲時,int/unsigned
是16位。最好保證代碼不會左移到符號位。
some_int % 255
執行簽名的餘數。在設備上,例如簡單的嵌入式設備,無符號的餘數肯定會更快或更快。 % 255u
沒有什麼可以丟失的,但是可能有所改進。
[編輯]
雖然OP已經爲短字符串的「固定」的代碼,它違背了fletcher16()
的設計參數,其執行速度。
細節:如果我們拋開%255
,sum1
是data[0] + ... + data[count-1]
)和sum2
是data[0]*(count) + data[0]*(count-1) + ... + data[count-1]*(1)
,就很容易產生1,2,3等長字符串與招致一些低價值,如果有的話,%255
操作。
請注意,sum2
是根據訂單有效創建不同校驗和的部分。如果數組元素的總和永遠不會達到255(這發生在OP的4個測試用例中),則sum1
對於任何僅按順序不同的2個字符串都是相同的。
要有效地「混合/散列」具有較低值的短字符串,需要使用不同的算法。
也許只有當使用一個count < 8
變種:
sum1 = (sum1 + index + data[index]) % 255;
「的中用OR指數」 丟棄信息。 「異或索引」或「添加」會更有意義。 – chux
用XOR代替OR也會改變這個問題。 –
@MichaelFoukarakis改變XOR不會改變這3個問題的答案,因爲它們都指的是缺少'(X)OR索引'的始發者算法。它確實會影響建議改進的質量。 – chux