CRC校验修改随机数与CRC-16做除法运算
时间: 2023-12-23 13:02:56 浏览: 41
CRC校验是一种常用的数据检验方法,常用于数据通信和存储领域。CRC校验的基本原理是将要发送的数据通过一个固定的算法计算出一个校验码,接收方也通过相同的算法计算接收到的数据的校验码,并将其与发送方发送的校验码进行比较,以判断数据是否正确。
在CRC校验中,修改随机数会导致最终计算出的校验码不同。而CRC-16是一种常用的CRC校验算法,它使用一个16位的多项式进行除法运算来计算校验码。
具体来说,CRC-16是通过将要发送的数据与一个16位的预设值进行异或操作,然后进行16位的除法运算得到校验码。如果在发送过程中修改了随机数,那么最终计算出的校验码也会不同。
举个例子,假设要发送的数据为0x12345678,预设值为0xFFFF,那么计算过程如下:
1. 将0x12345678与0xFFFF进行异或操作,得到0xEDCB。
2. 将0xEDCB与16位的多项式0x8005进行异或操作,得到0x9D25。
3. 将0x9D25左移1位,得到0x3A4A。
4. 将0x3A4A与0x8005进行异或操作,得到0xC18F。
5. 将0xC18F左移1位,得到0x837E。
6. 将0x837E与0x8005进行异或操作,得到0x3A23。
7. 将0x3A23左移1位,得到0x7446。
8. 将0x7446与0x8005进行异或操作,得到0x4E2D。
最终计算出的校验码为0x4E2D。如果修改了随机数,那么最终计算出的校验码也会不同。
相关问题
根据CSMA/CD算法和CRC校验,C语言编写以太网结点的帧和帧接收发送流程并逐句解释
以太网是一种广泛使用的局域网技术,它采用CSMA/CD算法和CRC校验来实现数据的传输和错误检测。下面是一个用C语言编写的简单的以太网结点的帧和帧接收发送流程,并且逐句解释:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_DATA_LEN 1024 // 最大数据长度
#define ETHERNET_HEADER_LEN 14 // 以太网帧头长度
#define CRC_LEN 4 // CRC校验长度
// 定义一个以太网帧的结构体
typedef struct {
unsigned char dest_mac[6]; // 目标MAC地址
unsigned char src_mac[6]; // 源MAC地址
unsigned short type; // 协议类型
unsigned char data[MAX_DATA_LEN]; // 数据
unsigned int crc; // CRC校验
} EthernetFrame;
// 生成随机的MAC地址
void generate_mac_address(unsigned char mac_address[]) {
int i;
for (i = 0; i < 6; i++) {
mac_address[i] = rand() % 256;
}
}
// 计算CRC校验码
unsigned int calculate_crc(unsigned char data[], int len) {
unsigned int crc = 0xffffffff;
int i, j;
for (i = 0; i < len; i++) {
crc ^= data[i];
for (j = 0; j < 8; j++) {
if (crc & 0x00000001) {
crc = (crc >> 1) ^ 0xedb88320;
} else {
crc >>= 1;
}
}
}
return crc;
}
// 发送帧
void send_frame(EthernetFrame frame) {
printf("正在发送帧...\n");
// TODO: 将帧发送到网络中
printf("帧发送成功!\n");
}
// 接收帧
EthernetFrame receive_frame() {
EthernetFrame frame;
printf("正在接收帧...\n");
// TODO: 从网络中接收帧
printf("帧接收成功!\n");
return frame;
}
int main() {
srand(time(NULL)); // 初始化随机数种子
// 生成随机的MAC地址
unsigned char src_mac[6];
generate_mac_address(src_mac);
unsigned char dest_mac[6];
generate_mac_address(dest_mac);
// 构造帧头
EthernetFrame frame;
memcpy(frame.src_mac, src_mac, 6);
memcpy(frame.dest_mac, dest_mac, 6);
frame.type = 0x0800; // IP协议类型
// 构造数据
char data[] = "Hello, world!";
int data_len = strlen(data);
memcpy(frame.data, data, data_len);
// 计算CRC校验码
frame.crc = calculate_crc((unsigned char *)&frame, ETHERNET_HEADER_LEN + data_len);
// 发送帧
send_frame(frame);
// 接收帧
EthernetFrame received_frame = receive_frame();
// 检查CRC校验码是否正确
unsigned int crc = calculate_crc((unsigned char *)&received_frame, ETHERNET_HEADER_LEN + data_len + CRC_LEN);
if (crc == 0) {
printf("CRC校验成功!\n");
printf("接收到的数据为:%s\n", received_frame.data);
} else {
printf("CRC校验失败!\n");
}
return 0;
}
```
代码解释:
1. `#include <stdio.h>` 和 `#include <stdlib.h>` 是C语言的标准头文件,分别包含了输入输出和随机数生成等函数的定义。
2. `#include <string.h>` 包含了字符串处理函数的定义。
3. `#define MAX_DATA_LEN 1024` 定义了最大数据长度的常量。
4. `#define ETHERNET_HEADER_LEN 14` 定义了以太网帧头长度的常量。
5. `#define CRC_LEN 4` 定义了CRC校验长度的常量。
6. `typedef struct {...} EthernetFrame` 定义了一个以太网帧的结构体,包含了目标MAC地址、源MAC地址、协议类型、数据和CRC校验等字段。
7. `generate_mac_address()` 函数用于生成随机的MAC地址。
8. `calculate_crc()` 函数用于计算CRC校验码。
9. `send_frame()` 函数用于发送帧。在实际应用中,需要将帧发送到网络中。
10. `receive_frame()` 函数用于接收帧。在实际应用中,需要从网络中接收帧。
11. `memcpy()` 函数用于复制内存。
12. `srand(time(NULL))` 初始化了随机数生成器的种子,使得每次运行程序生成的随机数都不同。
13. `generate_mac_address()` 函数生成了源MAC地址和目标MAC地址。
14. `frame` 结构体包含了源MAC地址、目标MAC地址、协议类型、数据和CRC校验等字段。
15. `memcpy(frame.src_mac, src_mac, 6)` 复制了源MAC地址。
16. `memcpy(frame.dest_mac, dest_mac, 6)` 复制了目标MAC地址。
17. `frame.type = 0x0800` 设置了协议类型为IP。
18. `memcpy(frame.data, data, data_len)` 复制了数据。
19. `frame.crc = calculate_crc((unsigned char *)&frame, ETHERNET_HEADER_LEN + data_len)` 计算了CRC校验码。
20. `send_frame(frame)` 发送了帧。
21. `EthernetFrame received_frame = receive_frame()` 接收了帧。
22. `calculate_crc((unsigned char *)&received_frame, ETHERNET_HEADER_LEN + data_len + CRC_LEN)` 计算了接收到的帧的CRC校验码。
23. `printf()` 函数用于输出提示信息和接收到的数据。
24. `if (crc == 0)` 判断CRC校验码是否正确。
25. 程序退出。
总体来说,这个程序实现了一个简单的以太网结点的帧和帧接收发送流程。在实际应用中,需要将帧发送到网络中并从网络中接收帧,并且需要实现更复杂的帧处理和错误检测等功能。
BLE 使用CSRK签名和校验的具体过程
BLE使用CSRK来提供数据完整性和认证。下面是BLE使用CSRK签名和校验的具体过程:
1. 签名过程
发送方设备使用CSRK对数据包进行数字签名。具体过程如下:
1.1 选择一个随机数作为随机数(随机数的长度为8字节)。
1.2 计算数据包的CRC32值(CRC32值的长度为4字节)。
1.3 将随机数和CRC32值连接在一起,得到一个12字节的消息。
1.4 对消息进行AES-CMAC算法计算,得到一个4字节的签名值。
1.5 将签名值添加到数据包中。
2. 校验过程
接收方设备使用发送方设备的CSRK和IRK来解析发送方设备的地址,并使用CSRK验证数据包的签名。具体过程如下:
2.1 使用IRK解析发送方设备的地址。
2.2 使用CSRK对数据包进行数字签名验证。
2.3 如果验证成功,则接收方设备确认数据包的来源是发送方设备,并且数据包没有被篡改。
2.4 如果验证失败,则接收方设备将丢弃该数据包,并且不会响应该数据包。
这样,使用CSRK签名和校验可以确保BLE连接中传输的数据包的完整性和来源认证。同时,由于CSRK是一个128位的密钥,攻击者难以破解,因此可以提高BLE连接的安全性。