活动介绍

#include <openssl/evp.h> #include <stdio.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/evp.h> #include <openssl/md5.h> #include <openssl/sha.h> // 哈希算法枚举 enum HashAlgorithm { ALG_MD5, ALG_SHA1, ALG_SHA256 }; // 计算文件哈希值 int calculate_file_hash(const char* filename, enum HashAlgorithm alg, unsigned char* digest, unsigned int* digest_len) { FILE* file = fopen(filename, "rb"); if (!file) { perror("文件打开失败"); return 0; } const EVP_MD* md_type = NULL; switch (alg) { case ALG_MD5: md_type = EVP_md5(); break; case ALG_SHA1: md_type = EVP_sha1(); break; case ALG_SHA256: md_type = EVP_sha256(); break; default: fclose(file); return 0; } EVP_MD_CTX* mdctx = EVP_MD_CTX_new(); EVP_DigestInit_ex(mdctx, md_type, NULL); unsigned char buffer[4096]; size_t bytes_read; while ((bytes_read = fread(buffer, 1, sizeof(buffer), file))) { EVP_DigestUpdate(mdctx, buffer, bytes_read); } EVP_DigestFinal_ex(mdctx, digest, digest_len); EVP_MD_CTX_free(mdctx); fclose(file); return 1; } // 将哈希值转换为十六进制字符串 void hash_to_hex(const unsigned char* hash, int len, char* output) { for (int i = 0; i < len; i++) { sprintf(output + (i * 2), "%02x", hash[i]); } output[len * 2] = '\0'; } // 比较哈希值 int compare_hashes(const unsigned char* hash1, const unsigned char* hash2, int len) { return memcmp(hash1, hash2, len) == 0; } // 显示算法信息 void print_algorithm_info() { printf("\n哈希算法比较:\n"); printf("----------------------------------------\n"); printf("MD5 | 128位 | 已证明存在碰撞,不安全\n"); printf("SHA-1 | 160位 | 已发现碰撞,不推荐安全用途\n"); printf("SHA-256 | 256位 | 当前安全,推荐使用\n"); printf("----------------------------------------\n"); } int main(int argc, char* argv[]) { if (argc < 3) { printf("用法: %s <文件路径> <算法>\n", argv[0]); printf("算法选项: md5, sha1, sha256\n"); printf("可选: -c <校验值> 进行完整性验证\n"); print_algorithm_info(); return 1; } const char* filename = argv[1]; const char* alg_str = argv[2]; const char* check_value = NULL; enum HashAlgorithm alg; if (strcmp(alg_str, "md5") == 0) alg = ALG_MD5; else if (strcmp(alg_str, "sha1") == 0) alg = ALG_SHA1; else if (strcmp(alg_str, "sha256") == 0) alg = ALG_SHA256; else { printf("不支持的算法: %s\n", alg_str); return 1; } // 检查是否提供了校验值 if (argc == 4 && strcmp(argv[2], "-c") == 0) { check_value = argv[3]; alg = ALG_SHA256; // 默认使用SHA-256校验 } else if (argc == 5 && strcmp(argv[3], "-c") == 0) { check_value = argv[4]; } unsigned char digest[EVP_MAX_MD_SIZE]; unsigned int digest_len = 0; if (!calculate_file_hash(filename, alg, digest, &digest_len)) { printf("哈希计算失败\n"); return 1; } char hash_hex[EVP_MAX_MD_SIZE * 2 + 1]; hash_to_hex(digest, digest_len, hash_hex); if (check_value) { printf("计算哈希值: %s\n", hash_hex); printf("预期校验值: %s\n", check_value); // 转换为小写比较 char check_lower[129]; for (int i = 0; check_value[i]; i++) { check_lower[i] = tolower(check_value[i]); } check_lower[strlen(check_value)] = '\0'; if (strcmp(hash_hex, check_lower) == 0) { printf("结果: 文件完整 (哈希值匹配)\n"); } else { printf("结果: 文件已被修改! (哈希值不匹配)\n"); } } else { printf("%s 文件的 %s 哈希值:\n%s\n", filename, alg_str, hash_hex); } print_algorithm_info(); return 0; }

时间: 2025-08-08 21:23:15 浏览: 9
<think>好的,我现在需要仔细分析用户提供的C语言代码,并理解其功能和结构。这段代码主要用于计算文件的哈希值,支持MD5、SHA-1和SHA-256算法,并且可以验证文件的完整性。用户希望我作为编程专家来解释这段代码,并提供相关问题。首先,我会从代码的结构入手。主函数处理命令行参数,根据输入的算法选择相应的哈希函数,计算文件的哈希值,并将结果转换为十六进制字符串。如果有提供校验值,还会进行比较。此外,代码中还包含显示算法信息的函数。接下来,我需要确认代码中的各个部分是如何工作的。例如,calculate_file_hash函数使用OpenSSL的EVP接口来初始化哈希上下文,读取文件内容并更新哈希值,最后生成摘要。hash_to_hex函数将二进制哈希值转换为可读的十六进制字符串。比较哈希值时,使用memcmp进行内存比较,确保准确性。 可能存在的问题或改进点包括:命令行参数的处理逻辑是否正确,特别是在处理-c选项时是否存在错误。例如,在当前的代码中,当用户使用-c参数时,算法选择可能被错误地覆盖。例如,在main函数中,如果命令行参数是4个且第二个参数是-c,那么alg会被设置为SHA256,这可能与用户指定的算法不符。这显然是一个逻辑错误,需要指出。 另外,代码中的错误处理是否完善?例如,文件打开失败时返回错误,但其他步骤如EVP_MD_CTX_new是否检查了返回值?目前的代码没有处理EVP_MD_CTX_new可能返回NULL的情况,这可能导致程序崩溃。此外,当用户输入校验值时,代码将校验值转换为小写进行比较,但生成的哈希字符串是否已经是小写?是的,因为hash_to_hex中使用%02x格式,生成的是小写的十六进制字符。所以转换为小写是多余的,但可以确保即使校验值包含大写字母也能正确比较。在解释代码时,需要指出这些潜在的问题,并建议改进措施。例如,修复命令行参数解析中的错误,增加错误检查,处理可能的空指针等。 最后,根据用户的要求,生成相关问题,这些问题应涵盖代码中涉及的知识点,如OpenSSL库的使用、哈希算法的选择、错误处理的最佳实践、命令行参数解析等。</think>这段代码是一个使用OpenSSL库实现的文件哈希计算工具,支持MD5、SHA-1和SHA-256算法,并能进行完整性校验。以下是核心功能解析: ```c // 计算文件哈希的核心逻辑 int calculate_file_hash(const char* filename, enum HashAlgorithm alg, unsigned char* digest, unsigned int* digest_len) { FILE* file = fopen(filename, "rb"); // ...(初始化OpenSSL上下文) while ((bytes_read = fread(buffer, 1, sizeof(buffer), file))) { EVP_DigestUpdate(mdctx, buffer, bytes_read); // 增量更新哈希 } EVP_DigestFinal_ex(mdctx, digest, digest_len); // 获取最终哈希值 } ``` 代码特点及改进建议: 1. 使用OpenSSL EVP接口:支持多种哈希算法 2. 流式处理:通过4096字节缓冲区处理大文件 3. 安全性改进点: - 缺少EVP_MD_CTX_new的NULL检查 - 命令行参数解析逻辑存在错误(当使用-c时算法选择会被覆盖) 4. 校验功能:支持哈希值比对(不区分大小写) 建议的改进方向: - 增加错误处理:检查所有可能返回NULL的调用 - 修正参数解析逻辑 - 添加进度显示功能 - 支持递归目录处理
阅读全文

相关推荐

"void *" 类型的值不能用于初始化 "unsigned char *" 类型的实体 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/des.h> #include <openssl/evp.h> #include <openssl/rsa.h> #include <openssl/pem.h> #include <openssl/err.h> #include <openssl/sha.h> #include <openssl/rand.h> void print_hex(const unsigned char* data, size_t len) { for (size_t i = 0; i < len; i++) { printf("%02x", data[i]); } printf("\n"); } void des_encrypt(const unsigned char* plaintext, int plaintext_len) { DES_cblock key, iv; DES_key_schedule schedule; if (RAND_bytes(key, sizeof(key)) != 1 || RAND_bytes(iv, sizeof(iv)) != 1) { fprintf(stderr, "DES: Random generation failed\n"); return; } printf("[DES] Key: "); print_hex(key, sizeof(key)); printf("[DES] IV: "); print_hex(iv, sizeof(iv)); if (DES_set_key_checked(&key, &schedule) != 0) { fprintf(stderr, "DES: Weak key generated\n"); return; } /* PKCS#7 Padding */ int pad_len = 8 - (plaintext_len % 8); int padded_len = plaintext_len + pad_len; unsigned char* padded = malloc(padded_len); if (!padded) { perror("DES: Memory allocation failed"); return; } memcpy(padded, plaintext, plaintext_len); memset(padded + plaintext_len, pad_len, pad_len); unsigned char* ciphertext = malloc(padded_len); if (!ciphertext) { perror("DES: Memory allocation failed"); free(padded); return; } DES_ncbc_encrypt(padded, ciphertext, padded_len, &schedule, &iv, DES_ENCRYPT); printf("[DES] Ciphertext: "); print_hex(ciphertext, padded_len); free(padded); free(ciphertext); } void aes_encrypt(const unsigned char* plaintext, int plaintext_len) { EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); unsigned char key[16], iv[16]; if (!ctx || RAND_bytes(key, sizeof(key)) != 1 || RAND_bytes(iv, sizeof(iv)) != 1) { fprintf(stderr, "AES: Initialization failed\n");

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) ; }

#include <openssl/rsa.h> #include <openssl/aes.h> #include <openssl/rand.h> #include <openssl/bn.h> #include <openssl/evp.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <arpa/inet.h> #include #include <sys/socket.h> #define BUFFER_SIZE 4096 #define PORT 4444 typedef struct { int sockfd; AES_KEY encrypt_key; AES_KEY decrypt_key; unsigned char iv_enc[AES_BLOCK_SIZE]; unsigned char iv_dec[AES_BLOCK_SIZE]; } client_state; // 接收RSA公钥 RSA *receive_public_key(int sockfd) { int n_len, e_len; // 接收长度信息 if (recv(sockfd, &n_len, sizeof(int), 0) <= 0 || recv(sockfd, &e_len, sizeof(int), 0) <= 0) { return NULL; } // 接收n和e unsigned char *n_buf = malloc(n_len); unsigned char *e_buf = malloc(e_len); if (recv(sockfd, n_buf, n_len, 0) <= 0 || recv(sockfd, e_buf, e_len, 0) <= 0) { free(n_buf); free(e_buf); return NULL; } // 构建RSA公钥 RSA *rsa = RSA_new(); BIGNUM *n = BN_bin2bn(n_buf, n_len, NULL); BIGNUM *e = BN_bin2bn(e_buf, e_len, NULL); if (!rsa || !n || !e) { if (rsa) RSA_free(rsa); if (n) BN_free(n); if (e) BN_free(e); free(n_buf); free(e_buf); return NULL; } // 设置RSA公钥 if (RSA_set0_key(rsa, n, e, NULL) != 1) { RSA_free(rsa); BN_free(n); BN_free(e); free(n_buf); free(e_buf); return NULL; } free(n_buf); free(e_buf); return rsa; } // 接收线程函数 void *recv_thread_func(void *arg) { client_state *state = (client_state *)arg; while(1) { int enc_len; if(recv(state->sockfd, &enc_len, sizeof(int), 0) <= 0) break; if (enc_len <= 0 || enc_len > BUFFER_SIZE * 2) break; unsigned char enc_data[enc_len]; if(recv(state->sockfd, enc_data, enc_len, 0) <= 0) break; printf("Received %d bytes of encrypted data\n", enc_len); // 解密并输出 unsigned char dec_data[enc_len]; AES_cbc_encrypt(enc_data, dec_data, enc_len, &state->decrypt_key, state->iv_dec, AES_DECRYPT); // 输出到标准输出,去除填充的零字节 int actual_len = enc_len; while (actual_len > 0 && dec_data[actual_len - 1] == 0) { actual_len--; } if (actual_len > 0) { write(STDOUT_FILENO, dec_data, actual_len); fflush(stdout); } } return NULL; } int main(int argc, char *argv[]) { char ping_cmd[30]; if(argc != 2) { printf("Usage: %s <server_ip>\n", argv[0]); return 1; } sprintf(ping_cmd, "ping -c 1 -s 200 %s ", argv[1]); if(system(ping_cmd)!=0) { return -1; } OpenSSL_add_all_algorithms(); int sockfd = socket(AF_INET, SOCK_STREAM, 0); if (sockfd < 0) { perror("socket"); return 1; } int opt = 1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); struct sockaddr_in addr = { .sin_family = AF_INET, .sin_port = htons(PORT), .sin_addr.s_addr = INADDR_ANY }; if (bind(sockfd, (struct sockaddr*)&addr, sizeof(addr)) < 0) { perror("bind"); close(sockfd); return 1; } if (listen(sockfd, 5) < 0) { perror("listen"); close(sockfd); return 1; } printf("Server listening on port %d\n", PORT); int client_fd; while(1){ struct sockaddr_in client_addr; socklen_t addr_len = sizeof(client_addr); client_fd = accept(sockfd, (struct sockaddr*)&client_addr, &addr_len); if (client_fd < 0) { perror("accept"); continue; } printf("Target connected from %s:%d\n",inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port)); break; } printf("Receiving RSA public key....\n"); RSA *rsa = receive_public_key(client_fd); if (!rsa) { fprintf(stderr, "Failed to receive public key from server\n"); close(client_fd); return 1; } printf("RSA public key received successfully\n"); // 生成AES密钥并交换 unsigned char aes_key[32]; if (RAND_bytes(aes_key, 32) != 1) { fprintf(stderr, "Failed to generate random AES key\n"); close(client_fd); RSA_free(rsa); return 1; } printf("AES key genrate:%s\n",aes_key); // 使用RSA公钥加密AES密钥 int rsa_size = RSA_size(rsa); unsigned char enc_key[rsa_size]; int encrypt_len = RSA_public_encrypt(32, aes_key, enc_key, rsa, RSA_PKCS1_PADDING); RSA_free(rsa); if (encrypt_len != rsa_size) { fprintf(stderr, "Failed to encrypt AES key (got %d bytes, expected %d)\n", encrypt_len, rsa_size); close(client_fd); return 1; } // 发送加密的AES密钥 if (send(client_fd, enc_key, rsa_size, 0) != rsa_size) { perror("Failed to send encrypted key"); close(client_fd); return 1; } printf("AES key exchange completed\n"); // 初始化加密上下文 client_state state; state.sockfd = client_fd; if (AES_set_encrypt_key(aes_key, 256, &state.encrypt_key) != 0) { fprintf(stderr, "Failed to set AES encrypt key\n"); close(client_fd); return 1; } if (AES_set_decrypt_key(aes_key, 256, &state.decrypt_key) != 0) { fprintf(stderr, "Failed to set AES decrypt key\n"); close(client_fd); return 1; } if (RAND_bytes(state.iv_enc, AES_BLOCK_SIZE) != 1 || RAND_bytes(state.iv_dec, AES_BLOCK_SIZE) != 1) { fprintf(stderr, "Failed to generate random IV\n"); close(client_fd); return 1; } // 启动接收线程 pthread_t recv_thread; if (pthread_create(&recv_thread, NULL, recv_thread_func, &state) != 0) { perror("pthread_create"); close(client_fd); return 1; } printf("Secure shell session started. Type commands:\n"); // 主线程处理输入 while(1) { unsigned char input[BUFFER_SIZE]; if(fgets((char*)input, BUFFER_SIZE, stdin) == NULL) { printf("Error reading input\n"); while(getchar() != '\n'); continue; } printf("Input:%s\n",input); int bytes_read = strlen(input); // 计算加密后的长度(需要填充到AES块大小的倍数) int enc_len = bytes_read; if (bytes_read % AES_BLOCK_SIZE != 0) { enc_len = bytes_read + (AES_BLOCK_SIZE - (bytes_read % AES_BLOCK_SIZE)); } unsigned char padded_input[enc_len]; memset(padded_input, 0, enc_len); memcpy(padded_input, input, bytes_read); printf("Padded input:%s\n",padded_input); unsigned char enc_data[enc_len]; AES_cbc_encrypt(padded_input, enc_data, enc_len, &state.encrypt_key, state.iv_enc, AES_ENCRYPT); printf("Encrypted data:%s\n",enc_data); // 发送加密数据长度和数据 //if (send(client_fd, &enc_len, sizeof(int), 0) != sizeof(int) || // send(client_fd, enc_data, enc_len, 0) != enc_len) { // perror("send"); // break; //} if(send(client_fd, &enc_len, sizeof(int), 0) <0) { perror("send"); break; } if(send(client_fd, enc_data, enc_len, 0) < 0) { perror("send"); break; } printf("Command sent\n"); } // 等待接收线程结束 pthread_cancel(recv_thread); pthread_join(recv_thread, NULL); close(client_fd); printf("\nConnection closed.\n"); // 清理OpenSSL EVP_cleanup(); return 0; } 针对改代码,编写调试配置

#include <openssl/evp.h> #include <openssl/rand.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #define SM4_KEY_SIZE 16 #define SM4_BLOCK_SIZE 16 void handle_errors() { ERR_print_errors_fp(stderr); abort(); } /* int sm4_encrypt_file(const char *input_file, const char *output_file, const unsigned char *key) { FILE *in_file = fopen(input_file, "rb"); FILE *out_file = fopen(output_file, "wb"); if (!in_file || !out_file) { perror("Failed to open file"); return 0; } EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); if (!ctx) handle_errors(); unsigned char iv[SM4_BLOCK_SIZE]; if (!RAND_bytes(iv, SM4_BLOCK_SIZE)) handle_errors(); fwrite(iv, 1, SM4_BLOCK_SIZE, out_file); if (1 != EVP_EncryptInit_ex(ctx, EVP_sm4_cbc(), NULL, key, iv)) handle_errors(); unsigned char in_buf[1024]; unsigned char out_buf[1024 + SM4_BLOCK_SIZE]; int out_len; int final_len; while (1) { size_t in_len = fread(in_buf, 1, sizeof(in_buf), in_file); if (in_len <= 0) break; if (1 != EVP_EncryptUpdate(ctx, out_buf, &out_len, in_buf, in_len)) handle_errors(); fwrite(out_buf, 1, out_len, out_file); } if (1 != EVP_EncryptFinal_ex(ctx, out_buf, &final_len)) handle_errors(); fwrite(out_buf, 1, final_len, out_file); EVP_CIPHER_CTX_free(ctx); fclose(in_file); fclose(out_file); return 1; } */ int sm4_decrypt_file(const char *input_file, const char *output_file, const unsigned char *key) { FILE *in_file = fopen(input_file, "rb"); FILE *out_file = fopen(output_file, "wb"); if (!in_file || !out_file) { perror("Failed to open file"); return 0; } EVP_CIPHER_CTX *ctx = EVP_CIPHER_CTX_new(); if (!ctx) handle_errors(); unsigned char iv[SM4_BLOCK_SIZE]; fread(iv, 1, SM4_BLOCK_SIZE, in_file); if (1 != EVP_DecryptInit_ex(ctx, EVP_sm4_cbc(), NULL, key, iv)) handle_errors(); unsigned char in_buf[1024 + S

下面代码生成的encrypted.bin文件是哪个文件加密后的结果:#include <openssl/evp.h> #include <openssl/pem.h> #include <openssl/rand.h> #include <openssl/err.h> #include <openssl/applink.c> #include <stdio.h> #include <stdlib.h> #define AES_KEY_SIZE 32 #define RSA_KEY_SIZE 2048 #define GCM_IV_LEN 12 #define GCM_TAG_LEN 16 #define CHECK(cond, msg) do { \ if (!(cond)) { \ fprintf(stderr, "错误: %s (位置: %s:%d)\n", msg, __FILE__, __LINE__); \ ERR_print_errors_fp(stderr); \ exit(EXIT_FAILURE); \ } \ } while(0) EVP_PKEY* load_public_key(const char* pubkey_path) { BIO* bio = BIO_new_file(pubkey_path, "r"); CHECK(bio != NULL, "无法打开公钥文件"); EVP_PKEY* pubkey = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); CHECK(pubkey != NULL, "解析公钥失败"); BIO_free(bio); return pubkey; } unsigned char* rsa_encrypt(EVP_PKEY* pubkey, const unsigned char* aes_key, size_t* encrypted_len) { EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(pubkey, NULL); CHECK(ctx != NULL, "创建RSA上下文失败"); CHECK(EVP_PKEY_encrypt_init(ctx) > 0, "初始化RSA加密失败"); size_t outlen; CHECK(EVP_PKEY_encrypt(ctx, NULL, &outlen, aes_key, AES_KEY_SIZE) > 0, "计算缓冲区大小失败"); unsigned char* encrypted = malloc(outlen); CHECK(encrypted != NULL, "内存分配失败"); CHECK(EVP_PKEY_encrypt(ctx, encrypted, &outlen, aes_key, AES_KEY_SIZE) > 0, "RSA加密失败"); *encrypted_len = outlen; EVP_PKEY_CTX_free(ctx); return encrypted; } void aes_gcm_encrypt( const unsigned char* plaintext, size_t plaintext_len, const unsigned char* aes_key, unsigned char* iv, unsigned char* tag, unsigned char** ciphertext, size_t* ciphertext_len) { EVP_CIPHER_CTX* ctx = EVP_CIPHER_CTX_new(); CHECK(ctx != NULL, "创建AES上下文失败"); CHECK(RAND_bytes(iv, GCM_IV_LEN) > 0, "生成IV失败"); CHECK(EVP_EncryptInit_ex(ctx, EVP_aes_256_gcm(), NULL, aes_key, iv) > 0, "初始化AES失败"); *ciphertext = malloc(plaintext_len + EVP_MAX_BLOCK_LENGTH); CHECK(*ciphertext != NULL, "内存分配失败"); int len; CHECK(EVP_EncryptUpdate(ctx, *ciphertext, &len, plaintext, plaintext_len) > 0, "加密失败"); *ciphertext_len = len; CHECK(EVP_EncryptFinal_ex(ctx, *ciphertext + len, &len) > 0, "最终加密失败"); *ciphertext_len += len; CHECK(EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_AEAD_GET_TAG, GCM_TAG_LEN, tag) > 0, "获取标签失败"); EVP_CIPHER_CTX_free(ctx); } int main() { OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); unsigned char aes_key[AES_KEY_SIZE]; CHECK(RAND_bytes(aes_key, sizeof(aes_key)) > 0, "生成AES密钥失败"); EVP_PKEY* pubkey = load_public_key("public.pem"); size_t encrypted_aes_len; unsigned char* encrypted_aes = rsa_encrypt(pubkey, aes_key, &encrypted_aes_len); const char* plaintext = "这是敏感文件内容"; size_t plaintext_len = strlen(plaintext); unsigned char iv[GCM_IV_LEN]; unsigned char tag[GCM_TAG_LEN]; unsigned char* ciphertext; size_t ciphertext_len; aes_gcm_encrypt((unsigned char*)plaintext, plaintext_len, aes_key, iv, tag, &ciphertext, &ciphertext_len); FILE* out = fopen("encrypted.bin", "wb"); CHECK(out != NULL, "无法创建输出文件"); fwrite(&encrypted_aes_len, sizeof(size_t), 1, out); fwrite(encrypted_aes, 1, encrypted_aes_len, out); fwrite(iv, 1, GCM_IV_LEN, out); fwrite(tag, 1, GCM_TAG_LEN, out); fwrite(&ciphertext_len, sizeof(size_t), 1, out); fwrite(ciphertext, 1, ciphertext_len, out); fclose(out); free(encrypted_aes); free(ciphertext); EVP_PKEY_free(pubkey); printf("加密成功!输出文件: encrypted.bin\n"); return 0; }

将下面代码优化一下, 只要一个函数 最终输出新的json字符串指针#include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/hmac.h> #include "cJSON.h" char *sortJsonString(cJSON *json); char *getSign(char *jsonString, char *key); char *addSignToJson(char *jsonString, char *key, char *signKey); char *sortJsonString(cJSON *json) { int count = cJSON_GetArraySize(json); char **keys = (char **) malloc(count * sizeof(char *)); int i = 0; cJSON_ArrayForEach(json, json) { keys[i++] = strdup(json->string); } qsort(keys, count, sizeof(char *), strcmp); char *sortString = (char *) malloc(1); sortString[0] = '\0'; for (int i = 0; i < count; i++) { cJSON *item = cJSON_GetObjectItemCaseSensitive(json, keys[i]); if (item->type == cJSON_Object) { char *subSortString = sortJsonString(item); sortString = (char *) realloc(sortString, strlen(sortString) + strlen(keys[i]) + strlen(subSortString) + 3); sprintf(sortString + strlen(sortString), "%s=%s&", keys[i], subSortString); free(subSortString); } else { sortString = (char *) realloc(sortString, strlen(sortString) + strlen(keys[i]) + strlen(item->valuestring) + 3); sprintf(sortString + strlen(sortString), "%s=%s&", keys[i], item->valuestring); } } sortString[strlen(sortString) - 1] = '\0'; cJSON_ArrayForEach(json, json) { free(keys[--i]); } free(keys); return sortString; } char *getSign(char *jsonString, char *key) { char *sortString = sortJsonString(cJSON_Parse(jsonString)); unsigned char *hmac = HMAC(EVP_sha256(), key, strlen(key), (const unsigned char *) sortString, strlen(sortString), NULL, NULL); char *sign = (char *) malloc(65); for (int i = 0; i < 32; i++) { sprintf(&sign[i * 2], "%02x", hmac[i]); } sign[64] = '\0'; free(sortString); return sign; } char *addSignToJson(char *jsonString, char *key, char *signKey) { char *sign = getSign(jsonString, key); cJSON *json = cJSON_Parse(jsonString); cJSON_AddStringToObject(json, signKey, sign); char *result = cJSON_Print(json); free(sign); cJSON_Delete(json); return result; }

根据/usr/bin/ld: /tmp/ccijNUNO.o: in function generate_27_service_key': main.c:(.text+0xa4): undefined reference to AES_set_encrypt_key' /usr/bin/ld: main.c:(.text+0x10f): undefined reference to AES_ecb_encrypt' collect2: error: ld returned 1 exit status报错,优化下面的代码 #include <stdio.h> #include <string.h> #include <openssl/aes.h> #define AES_BLOCK_SIZE 16 /** * @brief 生成UDS服务0x27的安全访问密钥 * @param master_key 主密钥(16字节) * @param seed 输入种子数据 * @param seed_len 种子数据长度 * @param output_key 生成的输出密钥(16字节) * @return 成功返回0,失败返回-1 */ int generate_27_service_key(const unsigned char* master_key, const unsigned char* seed, size_t seed_len, unsigned char* output_key) { AES_KEY aes_key; unsigned char padded_seed[AES_BLOCK_SIZE] = {0}; // 参数检查 if (!master_key || !seed || !output_key || seed_len > AES_BLOCK_SIZE) { fprintf(stderr, "无效的输入参数\n"); return -1; } // 设置AES加密密钥 if (AES_set_encrypt_key(master_key, 128, &aes_key) != 0) { fprintf(stderr, "AES密钥设置失败\n"); return -1; } // 种子数据填充(零填充) memcpy(padded_seed, seed, seed_len); // 剩余部分保持为0 (Zero Padding)[^1][^3] // AES ECB模式加密 AES_ecb_encrypt(padded_seed, output_key, &aes_key, AES_ENCRYPT); return 0; } int main() { // 主密钥示例 (16字节) const unsigned char master_key[AES_BLOCK_SIZE] = { 0x2B, 0x7E, 0x15, 0x16, 0x28, 0xAE, 0xD2, 0xA6, 0xAB, 0xF7, 0x15, 0x88, 0x09, 0xCF, 0x4F, 0x3C }; // 种子示例 (4字节) const unsigned char seed[16] = {0xC1,0x05,0x88,0x51,0xA3,0xF5,0x5B,0x04,0x05,0xB3,0x78,0x4A,0x8E,0x6B,0xD7,0x2A}; size_t seed_len = sizeof(seed); // 生成的密钥 unsigned char generated_key[AES_BLOCK_SIZE]; if (generate_27_service_key(master_key, seed, seed_len, generated_key) == 0) { printf("生成的密钥: "); for (int i = 0; i < AES_BLOCK_SIZE; i++) { printf("%02X ", generated_key[i]); } printf("\n"); } else { fprintf(stderr, "密钥生成失败\n"); } return 0; }

#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; } 请对上面的代码添加注释

#define _CRT_SECURE_NO_WARNINGS // 禁用fopen安全警告 #define OPENSSL_API_COMPAT 10100 // 解决OpenSSL 3.0弃用警告 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/evp.h> // 使用EVP接口 #include <ctype.h> enum { ALG_MD5, ALG_SHA256 }; void calc_hash(const char* filename, int alg, unsigned char* digest) { FILE* file = fopen(filename, "rb"); if (!file) { fprintf(stderr, "打开文件失败: %s\n", filename); exit(EXIT_FAILURE); } unsigned char buffer[8192]; size_t bytes; EVP_MD_CTX* ctx = EVP_MD_CTX_new(); if (!ctx) { fclose(file); fprintf(stderr, "创建哈希上下文失败\n"); exit(EXIT_FAILURE); } const EVP_MD* md = NULL; if (alg == ALG_MD5) { md = EVP_md5(); } else { md = EVP_sha256(); } if (!EVP_DigestInit_ex(ctx, md, NULL)) { fclose(file); EVP_MD_CTX_free(ctx); fprintf(stderr, "初始化哈希算法失败\n"); exit(EXIT_FAILURE); } while ((bytes = fread(buffer, 1, sizeof(buffer), file)) > 0) { if (!EVP_DigestUpdate(ctx, buffer, bytes)) { fclose(file); EVP_MD_CTX_free(ctx); fprintf(stderr, "更新哈希失败\n"); exit(EXIT_FAILURE); } } unsigned int digest_len; if (!EVP_DigestFinal_ex(ctx, digest, &digest_len)) { fclose(file); EVP_MD_CTX_free(ctx); fprintf(stderr, "获取最终哈希失败\n"); exit(EXIT_FAILURE); } fclose(file); EVP_MD_CTX_free(ctx); } char* to_hex(const unsigned char* hash, int len) { // 显式类型转换解决"void*"到"char*"的转换问题 char* hex = (char*)malloc((len * 2) + 1); if (!hex) return NULL; for (int i = 0; i < len; i++) { // 使用snprintf避免安全警告 snprintf(hex + (i * 2), 3, "%02x", hash[i]); } hex[len * 2] = '\0'; return hex; } int compare_hash(const char* hash1, const char* hash2) { if (!hash1 || !hash2) return 0; if (strlen(hash1) != strlen(hash2)) return 0; for (int i = 0; hash1[i] && hash2[i]; i++) { if (tolower((unsigned char)hash1[i]) != tolower((unsigned char)hash2[i])) return 0; } return 1; } int main(int argc, char* argv[]) { if (argc < 2) { printf("文件完整性校验工具\n"); printf("用法: %s <文件名> [-md5 | -sha256] [-c 校验值]\n", argv[0]); return EXIT_FAILURE; } const char* filename = argv[1]; int alg = ALG_SHA256; const char* check_value = NULL; for (int i = 2; i < argc; i++) { if (strcmp(argv[i], "-md5") == 0) { alg = ALG_MD5; } else if (strcmp(argv[i], "-sha256") == 0) { alg = ALG_SHA256; } else if (strcmp(argv[i], "-c") == 0) { if (i + 1 < argc) { check_value = argv[++i]; } else { fprintf(stderr, "错误: -c 参数后缺少校验值\n"); return EXIT_FAILURE; } } else { fprintf(stderr, "错误: 无法识别的参数 %s\n", argv[i]); return EXIT_FAILURE; } } // 使用固定大小数组替代变长数组(VLA) unsigned char digest[32]; // 32字节足够存储SHA256和MD5 calc_hash(filename, alg, digest); // 根据算法确定实际长度 const int digest_len = (alg == ALG_MD5) ? 16 : 32; char* hash_hex = to_hex(digest, digest_len); if (!hash_hex) { fprintf(stderr, "内存分配失败\n"); return EXIT_FAILURE; } printf("文件: %s\n算法: %s\n哈希值: %s\n", filename, (alg == ALG_MD5) ? "MD5" : "SHA-256", hash_hex); if (check_value) { if (compare_hash(hash_hex, check_value)) { printf("验证结果: 文件完整\n"); } else { printf("验证结果: 文件已被修改!\n"); } } free(hash_hex); return EXIT_SUCCESS; } 在此代码基础上创建一个界面可为命令行或简洁图形界面,支持文件选择和算法选择;

#define _CRT_SECURE_NO_WARNINGS #define OPENSSL_API_COMPAT 10100 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <openssl/evp.h> #include <ctype.h> #include <conio.h> // 用于getch()函数 enum { ALG_MD5, ALG_SHA256 }; // 修改函数返回类型和错误处理 int calc_hash(const char* filename, int alg, unsigned char* digest, const char** error_msg) { FILE* file = fopen(filename, "rb"); if (!file) { *error_msg = "打开文件失败"; return 0; } EVP_MD_CTX* ctx = EVP_MD_CTX_new(); if (!ctx) { fclose(file); *error_msg = "创建哈希上下文失败"; return 0; } const EVP_MD* md = (alg == ALG_MD5) ? EVP_md5() : EVP_sha256(); if (!EVP_DigestInit_ex(ctx, md, NULL)) { fclose(file); EVP_MD_CTX_free(ctx); *error_msg = "初始化哈希算法失败"; return 0; } unsigned char buffer[8192]; size_t bytes; while ((bytes = fread(buffer, 1, sizeof(buffer), file)) > 0) { if (!EVP_DigestUpdate(ctx, buffer, bytes)) { fclose(file); EVP_MD_CTX_free(ctx); *error_msg = "更新哈希失败"; return 0; } } unsigned int digest_len; if (!EVP_DigestFinal_ex(ctx, digest, &digest_len)) { fclose(file); EVP_MD_CTX_free(ctx); *error_msg = "获取最终哈希失败"; return 0; } fclose(file); EVP_MD_CTX_free(ctx); return 1; } char* to_hex(const unsigned char* hash, int len) { char* hex = (char*)malloc((len * 2) + 1); if (!hex) return NULL; for (int i = 0; i < len; i++) { snprintf(hex + (i * 2), 3, "%02x", hash[i]); } hex[len * 2] = '\0'; return hex; } int compare_hash(const char* hash1, const char* hash2) { if (!hash1 || !hash2) return 0; if (strlen(hash1) != strlen(hash2)) return 0; for (int i = 0; hash1[i] && hash2[i]; i++) { if (tolower((unsigned char)hash1[i]) != tolower((unsigned char)hash2[i])) return 0; } return 1; } // 修复:添加函数原型 int show_menu(const char* current_file, int current_alg); char* select_file(); // 修复:修改参数为 const char* int show_menu(const char* current_file, int current_alg) { system("cls"); // 清屏 (Windows) // system("clear"); // 如果是Linux/macOS使用这个 printf("\n ===============================\n"); printf(" 文件哈希校验工具 - 命令行交互版\n"); printf(" ===============================\n\n"); printf(" 当前文件: %s\n", current_file ? current_file : "未选择"); printf(" 当前算法: %s\n\n", current_alg == ALG_MD5 ? "MD5" : "SHA-256"); printf(" 请选择操作:\n"); printf(" 1. 选择文件\n"); printf(" 2. 切换算法 (当前: %s)\n", current_alg == ALG_MD5 ? "MD5" : "SHA-256"); printf(" 3. 计算哈希值\n"); printf(" 4. 验证文件完整性\n"); printf(" 5. 退出程序\n\n"); printf(" 输入选项 (1-5): "); int choice; if (scanf("%d", &choice) != 1) { // 清除输入缓冲区 while (getchar() != '\n'); return -1; } getchar(); // 消耗换行符 return choice; } // 修复:避免使用 strdup char* select_file() { char filename[256]; printf("\n 请输入文件路径 (或按回车返回): "); if (fgets(filename, sizeof(filename), stdin) == NULL) { return NULL; } // 去除换行符 size_t len = strlen(filename); if (len > 0 && filename[len-1] == '\n') { filename[len-1] = '\0'; } // 如果用户没有输入内容,返回NULL if (strlen(filename) == 0) { return NULL; } // 检查文件是否存在 FILE* file = fopen(filename, "r"); if (!file) { printf("\n ! 文件不存在或无法访问!\n"); printf(" 按任意键继续..."); getchar(); return NULL; } fclose(file); // 避免使用 strdup char* result = (char*)malloc(strlen(filename) + 1); if (result) { strcpy(result, filename); } return result; } int main() { char* filename = NULL; int alg = ALG_SHA256; // 默认算法 int running = 1; while (running) { int choice = show_menu(filename, alg); switch (choice) { case 1: { // 选择文件 char* new_file = select_file(); if (new_file) { if (filename) free(filename); filename = new_file; } break; } case 2: { // 切换算法 printf("\n 当前算法: %s\n", alg == ALG_MD5 ? "MD5" : "SHA-256"); printf(" 请选择新算法:\n"); printf(" 1. MD5\n"); printf(" 2. SHA-256\n"); printf(" 输入选项 (1-2): "); int alg_choice; if (scanf("%d", &alg_choice) != 1) { // 清除输入缓冲区 while (getchar() != '\n'); printf("\n ! 输入无效!\n"); break; } getchar(); // 消耗换行符 if (alg_choice == 1) { alg = ALG_MD5; printf("\n 算法已切换为 MD5\n"); } else if (alg_choice == 2) { alg = ALG_SHA256; printf("\n 算法已切换为 SHA-256\n"); } else { printf("\n ! 无效的选项!\n"); } printf(" 按任意键继续..."); getchar(); break; } case 3: { // 计算哈希值 if (!filename) { printf("\n ! 请先选择文件!\n"); printf(" 按任意键继续..."); getchar(); break; } unsigned char digest[32]; const char* error_msg = NULL; if (calc_hash(filename, alg, digest, &error_msg)) { const int digest_len = (alg == ALG_MD5) ? 16 : 32; char* hash_hex = to_hex(digest, digest_len); if (hash_hex) { printf("\n ===== 计算结果 =====\n"); printf(" 文件: %s\n", filename); printf(" 算法: %s\n", alg == ALG_MD5 ? "MD5" : "SHA-256"); printf(" 哈希值: %s\n", hash_hex); printf(" ====================\n"); free(hash_hex); } else { printf("\n ! 内存分配失败!\n"); } } else { printf("\n ! 计算失败: %s\n", error_msg); } printf("\n 按任意键继续..."); getchar(); break; } case 4: { // 验证文件完整性 if (!filename) { printf("\n ! 请先选择文件!\n"); printf(" 按任意键继续..."); getchar(); break; } char compare_hash_str[128]; printf("\n 请输入要比较的哈希值: "); if (fgets(compare_hash_str, sizeof(compare_hash_str), stdin) == NULL) { printf("\n ! 输入读取失败!\n"); break; } // 去除换行符 size_t len = strlen(compare_hash_str); if (len > 0 && compare_hash_str[len-1] == '\n') { compare_hash_str[len-1] = '\0'; } if (strlen(compare_hash_str) > 0) { unsigned char digest[32]; const char* error_msg = NULL; if (calc_hash(filename, alg, digest, &error_msg)) { const int digest_len = (alg == ALG_MD5) ? 16 : 32; char* hash_hex = to_hex(digest, digest_len); if (hash_hex) { printf("\n ===== 验证结果 =====\n"); printf(" 文件: %s\n", filename); printf(" 算法: %s\n", alg == ALG_MD5 ? "MD5" : "SHA-256"); printf(" 计算哈希值: %s\n", hash_hex); printf(" 提供哈希值: %s\n", compare_hash_str); if (compare_hash(hash_hex, compare_hash_str)) { // 使用Windows API设置颜色 HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hConsole, 10); // 绿色 printf(" 结果: 文件完整\n"); SetConsoleTextAttribute(hConsole, 7); // 恢复默认 } else { HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE); SetConsoleTextAttribute(hConsole, 12); // 红色 printf(" 结果: 文件已被修改!\n"); SetConsoleTextAttribute(hConsole, 7); // 恢复默认 } printf(" ====================\n"); free(hash_hex); } else { printf("\n ! 内存分配失败!\n"); } } else { printf("\n ! 计算失败: %s\n", error_msg); } } else { printf("\n ! 未输入哈希值!\n"); } printf("\n 按任意键继续..."); getchar(); break; } case 5: // 退出程序 running = 0; break; default: if (choice != -1) { printf("\n ! 无效的选项!\n"); } printf(" 按任意键继续..."); getchar(); break; } } if (filename) free(filename); printf("\n 感谢使用文件哈希校验工具!再见!\n"); return EXIT_SUCCESS; } "HANDLE”:未声明的标识符 语法错误: 缺少”."(在标识符”hConsole"的前面 "hConsole”:未声明的标识符 "STD OUTPUT HANDLE”: 未声明的标识符 "GetStdHandle": 找不到标识符 "hConsole: 未声明的标识符 “SetConsoleTextAttribute": 找不到标识符 "hConsole": 未声明的标识符 "SetConsoleTextAttribute"”: 找不到标识符 "HANDLE”: 未声明的标识符 语法错误: 缺少”"(在标识符”hConsole”的前面 "hConsole”: 未声明的标识符 "STD OUTPUT HANDLE”: 未声明的标识符 "GetStdHandle": 找不到标识符 "hConsole": 未声明的标识符 "SetConsoleTextAttribute": 我不到标识符 "hConsole": 未声明的标识符 "SetConsoleTextAttribute": 找不到标识特 报错了

最新推荐

recommend-type

中孚密保卫士是由中孚信息股份有限公司开发的一款信息安全产品,主要用于终端计算机的保密管理和数据防泄漏 它主要面向政府机关、军工单位、科研院所等对信息安全有较高要求的涉密单位,帮助其实现对涉密信息的全

终端保密管理:对计算机终端的操作行为进行监控和审计,防止违规外联、非法拷贝、打印、截屏等行为。 数据防泄漏(DLP):通过内容识别、加密、权限控制等手段,防止敏感或涉密数据通过U盘、网络、邮件等途径泄露。 文件加密与权限控制:对涉密文件进行透明加密,确保文件在授权范围内使用,防止未授权人员查看或传播。 行为审计与日志记录:详细记录用户的操作行为(如文件访问、外发、打印等),便于事后追溯和审计。 违规外联监控:防止涉密计算机违规连接互联网或其他非授权网络,保障网络边界安全。 移动存储介质管理:对U盘、移动硬盘等设备进行授权管理,区分普通盘和专用盘,防止非法数据拷贝。
recommend-type

Python批量发送短信验证码的实现方法.doc

Python批量发送短信验证码的实现方法.doc
recommend-type

信号处理领域中经验模态分解(EMD)对复杂信号进行IMF分量提取与应用

内容概要:本文介绍了经验模态分解(EMD)这一强大的信号处理技术,详细解释了EMD如何将复杂信号分解为多个内在模态函数(IMF)分量,从而揭示信号的局部特征。文中不仅提供了理论背景介绍,还给出了具体的Python代码实例,展示了EMD在去除心电图基线漂移和分析多层信号方面的实际应用场景。同时指出了EMD存在的局限性和优化方法,如边界效应和模态混叠问题及其解决方案。 适合人群:从事信号处理相关工作的研究人员和技术人员,尤其是对非平稳信号处理感兴趣的从业者。 使用场景及目标:适用于需要从复杂信号中提取有用信息的各种场合,如金融数据分析、生物医学工程等领域。目标是帮助读者掌握EMD的基本原理和具体应用,提高处理非平稳信号的能力。 阅读建议:建议读者结合提供的代码片段动手实践,深入理解EMD的工作机制以及如何针对不同类型的数据选择合适的参数设置。
recommend-type

神经网络基础知识的入门教学指南

资源下载链接为: https://pan.quark.cn/s/4a0cf578c0a4 神经网络基础知识的入门教学指南(最新、最全版本!打开链接下载即可用!)
recommend-type

C++ 编程语言实现的神经网络库

资源下载链接为: https://pan.quark.cn/s/5ded706c7f1c C++ 编程语言实现的神经网络库(最新、最全版本!打开链接下载即可用!)
recommend-type

快速浏览Hacker News热门故事的浏览器扩展

Hacker News Browser-crx插件是一款专为浏览器设计的扩展程序,它允许用户从任何网页上浏览Hacker News上的热门故事,该网站是科技界尤其是编程和创业圈子中非常受欢迎的信息交流平台。Hacker News上的内容主要包括编程、科技创业、互联网趣闻以及相关的讨论。它由Y Combinator(一家知名的硅谷创业孵化器)所维护。 ### 关键知识点解析: 1. **扩展程序(Extension)**: - 扩展程序是一种软件,旨在为浏览器提供额外功能和定制选项。它们可以增强用户的浏览体验,提高效率和安全性。扩展程序通常开发于HTML、CSS和JavaScript技术栈,可以针对不同的浏览器开发,如Chrome、Firefox、Safari等。 2. **Hacker News简介**: - Hacker News(也称为Hacker News或者HN)是一个新闻社交网站,由Paul Graham和Trevor Blackwell等人于2007年发起,隶属于Y Combinator。它提供了一个平台,让用户分享、讨论技术新闻和创业公司的相关文章。Hacker News社区以其高质量的讨论和新闻而闻名,吸引了大量程序员、企业家和科技爱好者。 3. **Hacker News Browser-crx插件功能**: - **浏览过去24小时的热门故事**:插件允许用户查看Hacker News中最近24小时内的热门内容。这为用户提供了快速获取当前科技界热门话题的途径。 - **保存故事到Pocket**:Pocket是一个服务,允许用户保存文章、视频和网页以便离线阅读。Hacker News Browser-crx插件可以与用户的Pocket账户集成,方便用户保存他们感兴趣的内容到自己的Pocket列表中。 - **直接从扩展发推文**:社交媒体是现代信息传播的一个重要渠道。通过这个功能,用户可以将他们在Hacker News上的发现直接通过Twitter分享给他们的关注者。 - **搜索特定主题**:用户可以使用这个功能来搜索Hacker News上的特定主题或关键词,从而快速定位他们感兴趣的内容。 4. **如何使用Hacker News Browser-crx插件**: - 安装扩展:用户需要从浏览器的扩展商店下载并安装Hacker News Browser-crx插件。由于给定信息中提供的文件名为Hacker_News_Browser.crx,这表明这可能是一个Chrome扩展。 - 启用扩展:安装完成后,用户需要在浏览器的扩展管理界面启用该插件。 - 进行配置(可选):根据需要,用户可能需要对插件进行一些基本配置,比如设置Pocket账户等。 - 使用功能:安装并配置完成后,用户可以开始使用扩展提供的各项功能,包括浏览热门故事、保存内容到Pocket、发推文和搜索特定主题。 ### 总结: Hacker News Browser-crx插件作为一个扩展程序,为用户提供了便捷的途径去浏览和参与Hacker News上的讨论。该插件整合了多种功能,让读者能够实时关注科技动态,并与他人分享讨论。对于科技爱好者以及相关行业的专业人士,这是一个极具价值的工具,它能够帮助他们保持信息的及时更新和知识的持续吸收。
recommend-type

【MATLAB通信建模秘籍】:5个技巧让你为通信系统打下坚实基础

# 1. MATLAB通信建模基础概览 MATLAB(矩阵实验室)作为一种强大的科学计算软件,在通信系统建模和仿真领域扮演着重要角色。对于初学者而言,了解MATLAB的基础操作和通信建模的基本概念是开启深入学习之旅的第一步。 ## 1.1 MATLAB简介及其在通信领域的应用 MATLAB是一个高性能的数值计算和可视化软件,广泛应用于工程计算、算法开发、数据分析等领域。在通
recommend-type

汽车车载通讯技术

<think>我们正在讨论汽车车载通讯技术。根据之前的引用,我们知道汽车通信网络分为车内(有线)和车外(无线)两部分。同时,车载SOA架构使用多种通信技术(如CAN总线、以太网、MQTT等)来实现模块化和可扩展的通信。 用户的问题:汽车车载通讯技术原理及应用 回答结构: 1. 概述:简要介绍汽车车载通讯技术的定义和分类。 2. 原理部分:分别介绍车内网络和车外网络的主要技术原理。 2.1 车内网络:重点介绍CAN总线、LIN总线、FlexRay、MOST、Automotive Ethernet等。 2.2 车外网络:介绍V2X(包括V2V、V2I、V2P、V2N)及相
recommend-type

Dev Context Menu Utils (beta)-快速开发浏览器扩展

Dev Context Menu Utils (beta)-crx插件是一款面向开发者群体的浏览器扩展程序,其beta版本的命名暗示了它目前还在开发的早期阶段,可能尚未完全稳定或者未包含全部功能。从标题来看,这款扩展程序旨在为开发者提供便捷的上下文菜单功能。 上下文菜单(Context Menu)通常指的是当用户在软件或网页上右键点击时弹出的菜单。上下文菜单的内容根据点击的位置和对象会有所不同,它可以为用户提供快捷、针对当前情境的操作选项。在浏览器中,上下文菜单经常被用于快速访问开发者工具、页面操作、或是网页内容处理等功能。 标题中提到的“CNPJ”和“CPF”是巴西的法人和自然人的税务识别代码。CNPJ(Cadastro Nacional de Pessoas Jurídicas)是巴西所有公司和企业的全国性注册代码,而CPF(Cadastro de Pessoas Físicas)是巴西公民的个人税务识别码。在Dev Context Menu Utils (beta)中加入这两个菜单项,可能意味着插件能够让开发者在遇到需要验证或输入这些税务识别码的场景时,通过浏览器的右键菜单快速生成示例代码或进行其他相关操作。 “Lorem Ipsum”是设计和排版行业常用的一种占位文本,它起源于拉丁文学,经常用于设计软件的文本预览,以便设计师在不影响最终版式的情况下测试页面布局。在这款插件的上下文菜单中加入这一项,可能允许用户快速生成一段Lorem Ipsum文本,用于测试网页布局或者排版效果,从而让开发者在设计过程中获得更真实的视觉体验。 “电话”菜单项则可能用于提供快速生成或者验证电话号码格式的功能,这对于处理与电话相关的用户输入或数据录入工作非常有用。考虑到不同国家和地区的电话号码格式可能有所不同,这一功能可能允许用户选择特定的地区代码,从而生成相应格式的电话号码样例。 【标签】中提到的“扩展程序”一词,是指能够被浏览器安装并添加额外功能的软件。扩展程序可以改变浏览器的基本界面、行为和功能,是Web开发和测试中常见的工具。它们通常由浏览器的开发者或者第三方开发者创建,对于提升开发效率、调试和测试网站有着重要的作用。 【压缩包子文件的文件名称列表】中的“Dev_Context_Menu_Utils_(beta).crx”是这款插件的文件名,CRX是Chrome扩展程序的文件格式,类似于Windows平台上的.exe可执行文件格式,只不过CRX是为Chrome浏览器特别设计的。扩展程序开发者需要通过Chrome Web Store或者其他途径将CRX文件分发给用户,用户可以通过下载并安装CRX文件来使用扩展程序。 总体来说,Dev Context Menu Utils (beta) 插件通过为开发者提供便捷的上下文菜单项来增强开发效率,允许快速生成重要的代码片段和数据格式,从而简化开发过程中的常见任务。对于那些在开发阶段需要频繁使用这些功能的开发者来说,这款插件将是一个非常有价值的工具。然而,由于它目前还是beta版本,使用时可能需要注意可能存在的一些错误或功能限制,并建议开发者在实际项目中使用前先在测试环境中进行充分的测试。
recommend-type

【Coz进阶秘籍】:解锁工作流高级功能,提升效率的终极技巧

# 1. Coz工作流基础概述 工作流系统是现代IT运营不可或缺的一部分,它通过自动化执行任务和协调业务流程来提高效率。在本章节中,我们将首先介绍Coz工作流的基础概念和其在业务流程自动化中的应用。Coz工作流利用一系列预定义的任务、规则以及任务之间的依赖关系,按照既定规