任意长度字节组的 Fletcher 校验和
Fletcher's Checksum for arbitrary length group of bytes
我正在尝试实现一个函数来计算可变长度内存区域的 8 位弗莱彻校验和,我的想法是我可以传递一个 2 字节短数组或 2kb 数组并使用相同的功能。我今天才研究它,所以我绝对不是校验和算法或指针算法方面的专家,而且我的代码几乎肯定充满错误。
基本上我的策略是传递一个指向组中第一个字节地址的指针,以及要扫描的内存区域的大小,只要大小总是sizeof(object being passed ), 这将是有效的。我可以在函数内计算 sizeof 以避免潜在的错误,但我认为我必须将接受的类型限制为特定类型。
现在据我了解,*(ptr + i),应该return位于ptr地址后第i个字节的值。我以前没有做过这样的事情,所以我可能误解了我读到的内容。
uint8_t fletcher_8(void *data, uint size){
data = (uint8_t *)data; // Recast pointer as uint8_t*
uint8_t sum1 = 0;
uint8_t sum2 = 0; // Initialise variables for algorithm
for (int i =0; i < size; i++){
sum1 += *(data + i); // get the value of the ith byte after the data pointer's address
sum2 += sum1;
}
sum1 %= 16; // modulo the first sum
sum1 << 4; // shift lower four bits to the upper four bits
sum2 %= 16; // modulo the second sum
return sum1 + sum2; // add both sums (highest four bits are sum1, lower four bits are sum2
}
如果我完全疯了并且有任何更简单的方法来实现我正在尝试做的事情,我很想听听!
编辑:
我am特地问了一个C++的实现,不过上面的代码也可能是psudocode。我最想知道我的方法是否正确。
你的第一个版本比第二个好。
第二版中的一些错误:
data
不应该是void *
类型,否则*(data + i)
是编译时错误。 data = (uint8_t *)data;
什么都不做。
sum1 << 4;
错过一个 =
做任何事情:sum1 <<= 4;
i
和 size
应该是同一类型。我更喜欢size_t
,因为它是sizeof
returns.
类型
https://en.wikipedia.org/wiki/Fletcher%27s_checksum说高位应该是sum2
,你的是sum1
.
我会这样写
uint8_t fletcher_8(uint8_t *data, size_t size){
uint8_t sum1 = 0;
uint8_t sum2 = 0;
for (size_t i = 0; i < size; i++){
sum1 += data[i];
sum2 += sum1;
}
return (sum1 & 0xF) | (sum2 << 4);
}
或
uint8_t fletcher_8(uint8_t *data, size_t size){
uint8_t sum1 = 0;
uint8_t sum2 = 0;
while (size--){
sum1 += *data++;
sum2 += sum1;
}
return (sum1 & 0xF) | (sum2 << 4);
}
我正在尝试实现一个函数来计算可变长度内存区域的 8 位弗莱彻校验和,我的想法是我可以传递一个 2 字节短数组或 2kb 数组并使用相同的功能。我今天才研究它,所以我绝对不是校验和算法或指针算法方面的专家,而且我的代码几乎肯定充满错误。
基本上我的策略是传递一个指向组中第一个字节地址的指针,以及要扫描的内存区域的大小,只要大小总是sizeof(object being passed ), 这将是有效的。我可以在函数内计算 sizeof 以避免潜在的错误,但我认为我必须将接受的类型限制为特定类型。
现在据我了解,*(ptr + i),应该return位于ptr地址后第i个字节的值。我以前没有做过这样的事情,所以我可能误解了我读到的内容。
uint8_t fletcher_8(void *data, uint size){
data = (uint8_t *)data; // Recast pointer as uint8_t*
uint8_t sum1 = 0;
uint8_t sum2 = 0; // Initialise variables for algorithm
for (int i =0; i < size; i++){
sum1 += *(data + i); // get the value of the ith byte after the data pointer's address
sum2 += sum1;
}
sum1 %= 16; // modulo the first sum
sum1 << 4; // shift lower four bits to the upper four bits
sum2 %= 16; // modulo the second sum
return sum1 + sum2; // add both sums (highest four bits are sum1, lower four bits are sum2
}
如果我完全疯了并且有任何更简单的方法来实现我正在尝试做的事情,我很想听听!
编辑:
我am特地问了一个C++的实现,不过上面的代码也可能是psudocode。我最想知道我的方法是否正确。
你的第一个版本比第二个好。
第二版中的一些错误:
data
不应该是void *
类型,否则*(data + i)
是编译时错误。data = (uint8_t *)data;
什么都不做。sum1 << 4;
错过一个=
做任何事情:sum1 <<= 4;
i
和size
应该是同一类型。我更喜欢size_t
,因为它是sizeof
returns. 类型
https://en.wikipedia.org/wiki/Fletcher%27s_checksum说高位应该是
sum2
,你的是sum1
.
我会这样写
uint8_t fletcher_8(uint8_t *data, size_t size){
uint8_t sum1 = 0;
uint8_t sum2 = 0;
for (size_t i = 0; i < size; i++){
sum1 += data[i];
sum2 += sum1;
}
return (sum1 & 0xF) | (sum2 << 4);
}
或
uint8_t fletcher_8(uint8_t *data, size_t size){
uint8_t sum1 = 0;
uint8_t sum2 = 0;
while (size--){
sum1 += *data++;
sum2 += sum1;
}
return (sum1 & 0xF) | (sum2 << 4);
}