char* Calculate_Crc16(char* data, int len) { if (len > 0) { USHORT crc = 0xFFFF; for (int i = 0;i < len;++i) { crc = (USHORT)(crc ^ data[i]); for (int j = 0;j < 8;j++) { if (crc = (crc & 1) != 0) { (USHORT)((crc >> 1) ^ 0xA001); } else { USHORT(crc >> 1); } } } crc16[0] = ((crc ^ 0xFF00) >> 8);//CRC校验高位 crc16[1] = (crc ^ 0x00FF); //CRC校验低位 std::cout<<"高位"<<std::hex<<(unsigned int)crc16[0]<<std::endl;//测试用打印,可删 std::cout<<"低位" << std::hex <<(unsigned int) crc16[1] << std::endl; return crc16; } return crc16; };
时间: 2024-02-14 08:30:46 浏览: 87
这段代码是一个计算 CRC16 校验值的函数,它接受一个指向字符数组的指针和数组的长度作为参数,并返回一个指向计算得到的 CRC16 校验值的字符数组指针。
该函数使用了 CRC16 校验算法来计算校验值。具体的计算过程如下:
1. 首先,初始化一个 16 位的变量 crc 为 0xFFFF。
2. 然后,遍历输入的数据数组,对每个字符进行处理。
3. 对于每个字符,使用异或运算符 `^` 将其与 crc 进行异或运算,并将结果赋值给 crc。
4. 接下来,进行一个循环,重复 8 次。
5. 在循环中,首先判断 crc 的最低位是否为 1。如果是,则执行以下操作:
- 将 crc 右移一位,并与 0xA001 进行异或运算,并将结果赋值给 crc。
- 如果最低位不为 1,则只将 crc 右移一位,不进行异或运算。
6. 循环结束后,crc 的值即为计算得到的 CRC16 校验值。
7. 最后,通过异或运算和移位操作,将 CRC16 校验值分别存储在 crc16[0] 和 crc16[1] 中。
8. 函数返回 crc16 数组的指针。
请注意,代码中提供的 `crc16` 变量没有在代码中声明和定义,所以你需要在函数之前添加 `USHORT crc16[2];` 来声明和定义一个大小为 2 的 USHORT 类型的数组来存储 CRC16 校验值。
相关问题
#include<stdio.h> #include<string.h> #include<stdlib.h> #include<ctype.h> #include<openssl/hmac.h> char *signature_calculate(char *json_obj, char *key){ unsigned char *key_byte = (unsigned char *)key; char *sorted_json = to_url_query(json_obj); unsigned char *dataddd = (unsigned char *)sorted_json; unsigned char *signature = HMAC(EVP_sha256(), key_byte, strlen(key), dataddd, strlen(dataddd), NULL, NULL); char hex_signature = malloc(2 * EVP_MAX_MD_SIZE + 1); for(int i=0; i<EVP_MAX_MD_SIZE; i++) { sprintf(&hex_signature[i2], "%02x", signature[i]); } return hex_signature; } typedef struct { char key[256]; char value[256]; } KeyValue; int compare(const void a, const void b) { return strcmp(((KeyValue)a)->key, ((KeyValue)b)->key); } char *sort_dict(KeyValue *array, int size) { // 对KeyValue数组按ASCII码升序排序 qsort(array, size, sizeof(KeyValue), compare); char *query_list = malloc(size * 256); int len=0; for(int i=0; i<size; i++) { if(strlen(array[i].value)==0){ // 如果值为空或者空字符串则不拼接 continue; } char *key = array[i].key; char *value = array[i].value; if(isalpha(value[0]) && isalnum(value[1]) && strcmp(value, "true")!=0 && strcmp(value, "false")!=0) { sprintf(&query_list[len], "%s=%s&", key, value); } else { sprintf(&query_list[len], "%s="%s"&", key, value); } len = strlen(query_list); } if(len>0) { query_list[len-1] = 0; } return query_list; } char *to_url_query(char *json, char *prefix){ // 将json字符串转换为URL键值对形式的字符串 int len = strlen(json); KeyValue *array = malloc(len * sizeof(KeyValue)); int i=0; int j=0; int level=0; char *key; // 处理嵌套字典的键名 while(i<len){ if(json[i]=='{' || json[i]=='['){ level++; i++; } else if(json[i]=='}' || json[i]==']'){ level--; i++; } else if(json[i]==','){ array[j].value[i-array[j].key] = 0; i++; j++; } else if(json[i]==':'){ key = array[j].key; array[j].value[0] = 0; i++; } else if(json[i]=='"' && level%2==0){ i++; int k=0; while(json[i]!='"') { array[j].value[k] = json[i]; i++; k++; } array[j].value[k] = 0; i++; } else if(json[i]!=',' && json[i]!=':' && json[i]!=' '){ array[j].key[i-j] = json[i]; i++; } else { i++; } } array[j].value[i-array[j].key] = 0; j++; char *sorted_json = sort_dict(array, j); char *query_list = malloc(strlen(sorted_json)+1); if(strlen(prefix)>0){ sprintf(query_list, "%s.%s", prefix, sorted_json); } else { strcpy(query_list, sorted_json); } free(array); free(sorted_json); return query_list; } 请对上面的代码添加注释
```
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<ctype.h>
#include<openssl/hmac.h>
// 计算签名函数,接收一个JSON字符串和一个密钥字符串,返回一个签名字符串
char *signature_calculate(char *json_obj, char *key){
// 将密钥转换为unsigned char类型的指针
unsigned char *key_byte = (unsigned char *)key;
// 将JSON字符串转换为URL键值对形式的字符串
char *sorted_json = to_url_query(json_obj);
// 将URL键值对形式的字符串转换为unsigned char类型的指针
unsigned char *dataddd = (unsigned char *)sorted_json;
// 使用OpenSSL库的HMAC函数计算签名
unsigned char *signature = HMAC(EVP_sha256(), key_byte, strlen(key), dataddd, strlen(dataddd), NULL, NULL);
// 将签名字符串转换为十六进制形式的字符串并返回
char hex_signature = malloc(2 * EVP_MAX_MD_SIZE + 1);
for(int i=0; i<EVP_MAX_MD_SIZE; i++) {
sprintf(&hex_signature[i2], "%02x", signature[i]);
}
return hex_signature;
}
// 定义一个键值对结构体类型,用于存储键值对
typedef struct {
char key[256];
char value[256];
} KeyValue;
// 对KeyValue数组按ASCII码升序排序的比较函数
int compare(const void a, const void b) {
return strcmp(((KeyValue)a)->key, ((KeyValue)b)->key);
}
// 将KeyValue数组按ASCII码升序排序并拼接成URL键值对形式的字符串
char *sort_dict(KeyValue *array, int size) {
// 对KeyValue数组按ASCII码升序排序
qsort(array, size, sizeof(KeyValue), compare);
// 初始化一个字符串,用于存储拼接后的URL键值对形式的字符串
char *query_list = malloc(size * 256);
int len=0;
for(int i=0; i<size; i++) {
// 如果值为空或者空字符串则不拼接
if(strlen(array[i].value)==0){
continue;
}
char *key = array[i].key;
char *value = array[i].value;
// 如果值是字母或数字,则直接拼接
if(isalpha(value[0]) && isalnum(value[1]) && strcmp(value, "true")!=0 && strcmp(value, "false")!=0) {
sprintf(&query_list[len], "%s=%s&", key, value);
} else { // 否则需要将值加上双引号再拼接
sprintf(&query_list[len], "%s="%s"&", key, value);
}
len = strlen(query_list);
}
// 去掉最后一个&符号
if(len>0) {
query_list[len-1] = 0;
}
return query_list;
}
// 将JSON字符串转换为URL键值对形式的字符串
char *to_url_query(char *json, char *prefix){
// 计算JSON字符串的长度
int len = strlen(json);
// 初始化一个KeyValue数组,用于存储键值对
KeyValue *array = malloc(len * sizeof(KeyValue));
int i=0;
int j=0;
int level=0;
char *key;
// 处理嵌套字典的键名
while(i<len){
if(json[i]=='{' || json[i]=='['){ // 如果遇到{或[,则进入下一层级
level++;
i++;
} else if(json[i]=='}' || json[i]==']'){ // 如果遇到}或],则退出上一层级
level--;
i++;
} else if(json[i]==','){ // 如果遇到逗号,则处理下一个键值对
array[j].value[i-array[j].key] = 0;
i++;
j++;
} else if(json[i]==':'){ // 如果遇到冒号,则表示下一个字符串是值,保存键名
key = array[j].key;
array[j].value[0] = 0;
i++;
} else if(json[i]=='"' && level%2==0){ // 如果遇到双引号,则表示下一个字符串是键名或值
i++;
int k=0;
while(json[i]!='"') { // 保存双引号之间的字符串
array[j].value[k] = json[i];
i++;
k++;
}
array[j].value[k] = 0;
i++;
} else if(json[i]!=',' && json[i]!=':' && json[i]!=' '){ // 如果不是逗号、冒号或空格,则表示当前字符是键名的一部分
array[j].key[i-j] = json[i];
i++;
} else { // 否则忽略当前字符
i++;
}
}
// 保存最后一个键值对的值
array[j].value[i-array[j].key] = 0;
j++;
// 将KeyValue数组按ASCII码升序排序并拼接成URL键值对形式的字符串
char *sorted_json = sort_dict(array, j);
// 初始化一个字符串,用于存储拼接后的URL键值对形式的字符串
char *query_list = malloc(strlen(sorted_json)+1);
if(strlen(prefix)>0){ // 如果有前缀,则在拼接后的字符串前加上前缀
sprintf(query_list, "%s.%s", prefix, sorted_json);
} else { // 否则直接返回拼接后的字符串
strcpy(query_list, sorted_json);
}
// 释放内存
free(array);
free(sorted_json);
return query_list;
}
```
c语言 检查一下下面的代码 为什么函数中获取不到键值#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <openssl/ssl.h> #include <openssl/err.h> #include <openssl/hmac.h> #include <jansson.h> #include <time.h> #include <errno.h> #include <resolv.h> #include <netdb.h> char* calculate_signature(char* json_str, char* key) { json_t *root; json_error_t error; /* 从文件中读取 JSON 数据 */ root = json_load_file(json_str, 0, &error); /* 遍历 JSON 对象中的所有键值对,并获取键的名称 */ int key_count = json_object_size(root); printf("key_names %d\n", key_count); const char *key_name; json_t *value; const char **key_names = (const char **)malloc(key_count * sizeof(char *)); int i = 0; json_object_foreach(root, key_name, value) { key_name = json_object_iter_key(value); key_names[i] = key_name; i++; } printf("key_names %s\n", key_names[2]); //int str_num = i; // 计算字符串数组中的字符串数量 /* char **sorted_names = sort_strings(key_names, key_count); char* stringA = (char*)malloc(1); // 初始化为一个空字符串 stringA[0] = '\0'; size_t len = 0; for (int i = 0; i < str_num; i++) { char* key = sorted_names[i]; json_t* value = json_object_get(root, key); char* str = json_dumps(value, JSON_ENCODE_ANY | JSON_COMPACT); len += strlen(key) + strlen(str) + 2; // 2 是键值对之间的字符 stringA = (char*)realloc(stringA, len); strcat(stringA, key); strcat(stringA, "="); strcat(stringA, str); strcat(stringA, "&"); free(str); } free(sorted_names); stringA[strlen(stringA) - 1] = '\0'; // 去掉最后一个"&" printf("stringA%s\n", stringA); unsigned char* sign = (unsigned char*)malloc(EVP_MAX_MD_SIZE); unsigned int sign_len = 0; HMAC(EVP_sha256(), key, strlen(key), (unsigned char*)stringA, strlen(stringA), sign, &sign_len); // 计算HMAC-SHA256签名 char* signature = (char*)malloc(sign_len * 2 + 1); // 签名的十六进制表示 signature[0] = '\0'; // 初始化为一个空字符串 for (int i = 0; i < sign_len; i++) { sprintf(signature + i * 2, "%02x", sign[i]); } json_object_set_new(root, "sign", json_string(signature)); // 在json中添加"sign"参数 json_dumpf(root, stdout, JSON_ENCODE_ANY | JSON_COMPACT); // 输出带有"sign"参数的json字符串 json_decref(root); free(key_names); free(stringA); free(sign); printf("signature%s\n", signature); */ return("A"); } int main() { char *key="39cabdfaab8c4da09bd6e9823c527836"; char *sss="{\"timestamp\":1685509898,\"sdkVersion\":\"1.0.30_1\",\"vin\":\"LJUBMSA24PKFFF198\"}"; calculate_signature(sss, key) ; }
代码中的问题在于 `json_load_file` 函数的第一个参数应该是一个文件名字符串,而不是 JSON 字符串。因此,需要将 `calculate_signature` 函数中的第一个参数 `json_str` 修改为文件名。
修改后的代码如下:
```c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/hmac.h>
#include <jansson.h>
#include <time.h>
#include <errno.h>
#include <resolv.h>
#include <netdb.h>
char* calculate_signature(char* filename, char* key) {
json_t *root;
json_error_t error;
/* 从文件中读取 JSON 数据 */
root = json_load_file(filename, 0, &error);
if (!root) {
printf("Error in %s line %d: %s\n", error.source, error.line, error.text);
return NULL;
}
/* 遍历 JSON 对象中的所有键值对,并获取键的名称 */
int key_count = json_object_size(root);
printf("key_names %d\n", key_count);
const char *key_name;
json_t *value;
const char **key_names = (const char **)malloc(key_count * sizeof(char *));
int i = 0;
json_object_foreach(root, key_name, value) {
key_name = json_object_iter_key(value);
key_names[i] = key_name;
i++;
}
printf("key_names %s\n", key_names[2]);
//int str_num = i; // 计算字符串数组中的字符串数量
/*
char **sorted_names = sort_strings(key_names, key_count);
char* stringA = (char*)malloc(1); // 初始化为一个空字符串
stringA[0] = '\0';
size_t len = 0;
for (int i = 0; i < str_num; i++) {
char* key = sorted_names[i];
json_t* value = json_object_get(root, key);
char* str = json_dumps(value, JSON_ENCODE_ANY | JSON_COMPACT);
len += strlen(key) + strlen(str) + 2; // 2 是键值对之间的字符
stringA = (char*)realloc(stringA, len);
strcat(stringA, key);
strcat(stringA, "=");
strcat(stringA, str);
strcat(stringA, "&");
free(str);
}
free(sorted_names);
stringA[strlen(stringA) - 1] = '\0'; // 去掉最后一个"&"
printf("stringA%s\n", stringA);
unsigned char* sign = (unsigned char*)malloc(EVP_MAX_MD_SIZE);
unsigned int sign_len = 0;
HMAC(EVP_sha256(), key, strlen(key), (unsigned char*)stringA, strlen(stringA), sign, &sign_len); // 计算HMAC-SHA256签名
char* signature = (char*)malloc(sign_len * 2 + 1); // 签名的十六进制表示
signature[0] = '\0'; // 初始化为一个空字符串
for (int i = 0; i < sign_len; i++) {
sprintf(signature + i * 2, "%02x", sign[i]);
}
json_object_set_new(root, "sign", json_string(signature)); // 在json中添加"sign"参数
json_dumpf(root, stdout, JSON_ENCODE_ANY | JSON_COMPACT); // 输出带有"sign"参数的json字符串
json_decref(root);
free(key_names);
free(stringA);
free(sign);
printf("signature%s\n", signature);
*/
return("A");
}
int main() {
char *key="39cabdfaab8c4da09bd6e9823c527836";
char *filename="test.json";
calculate_signature(filename, key) ;
return 0;
}
```
另外,代码中还有一些注释掉的部分,需要先实现对应的函数才能使用。
阅读全文