- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我相信 TCP 校验和函数执行以下操作:
听起来很简单。因此,我编写了自己的通用 checksum
函数:
#include <inttypes.h>
#include <arpa/inet.h>
uint16_t checksum(uint16_t * data, int size) {
uint16_t sum = 0;
int i = 0, length = size / 2;
while (i < length) sum += data[i++];
if (size % 2) sum += data[i] & 0xFF00;
return htons(~sum);
}
但是其他人编写的checksum
函数似乎更复杂。例如:
uint16_t checksum(uint16_t * addr, int len) {
int nleft = len;
int sum = 0;
uint16_t * w = addr;
uint16_t answer = 0;
while (nleft > 1) {
sum += *w++;
nleft -= sizeof(uint16_t);
}
if (nleft == 1) {
*(uint8_t *) (&answer) = *(uint8_t *) w;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
answer = ~sum;
return (answer);
}
关于这段代码我有几个问题:
*(uint8_t *) (&answer) = *(uint8_t *) w;
实际上做了什么?为什么我们取总和为:
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
TCP checksum的计算方式有变化吗?
我真的不明白为什么我们做 sum = (sum >> 16) + (sum & 0xFFFF)
。考虑 sum
是 0xABCD
:
0xABCD >> 16 == 0x0000
0xABCD & 0xFFFF == 0xABCD
0x0000 + 0xABCD == 0xABCD
这似乎是一个多余的步骤。下一条语句 sum += (sum >> 16)
也是如此。
最佳答案
What does the statement *(uint8_t *) (&answer) = *(uint8_t *) w; actually do?
这会将 uint16_t
转换为 uint8_t
,因此只有 8 个最右边的位从 w
复制到 回答
。考虑:
uint16_t x = 0x1234;
uint16_t* w = &x; // *w = // 0001001000110100
*(uint16_t *) (&answer) = *(uint16_t *) w; // answer = 0001001000110100
*(uint8_t *) (&answer) = *(uint8_t *) w; // answer = 0000000000110100
Why do we take the sum as:
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
answer = ~sum;
和
是32 位。 65536 ≡ 1 mod 65535
,所以 end-around carry expression (sum & 0xffff) + (sum >> 16)
减少 sum
模 65535
。这是将任何(最终)结果进位添加回结果总和所必需的。
关于c++ - 了解 TCP 校验和函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22374040/
如何在 PHP 中生成 CRC-8 校验和? 最佳答案 function crcnifull ($dato, $byte) { static $PolyFull=0x8c; for ($i=0
我正在编写代码来使用 32 位无符号整数计算 CRC16。当尝试打印执行 CRC 操作的 XOR 函数的返回值时,它总是打印 0。我尝试了各种调试方法,例如打印语句,但是,我似乎无法弄清楚! 这是我的
ThinkPHP3.2.3验证码显示、刷新、校验 ,具体如下: 显示验证码 首先在Home/Controller下创建一个公共控制器PublicController
我想将自定义验证绑定(bind)到 TimePicker 自定义控件,但下面的代码显示“无法将内容添加到 TimePicker 的对象类型。”。
目录 Spring 校验(validator,JSR-303)实现 什么是JSR-303规范 与Spring MVC结合 实体类添加
导包和配置 导入 JSR 303 的包、hibernate valid 的包 ?
我是一名优秀的程序员,十分优秀!