当前位置: 首页 > news >正文

OpenSSL 编程示例

参考:深入探索 OpenSSL:概念、原理、开发步骤、使用方法、使用场景及代码示例
地址:https://oneisall.blog.csdn.net/article/details/131489812?spm=1001.2014.3001.5502

目录

  • 1. OpenSSL 概念
  • 2. OpenSSL 原理
  • 3. OpenSSL 开发步骤
  • 4. OpenSSL 使用方法
  • 5. OpenSSL 应用场景
  • pdf 教程代码

当涉及到网络通信和数据传输的安全性时,OpenSSL 是一个非常重要的工具和库。它是一个开源软件包,提供了广泛的加密和安全功能。在本博客中,我们将详细介绍 OpenSSL 的概念、原理、开发步骤、使用方法、使用场景,并结合代码示例进行说明。

1. OpenSSL 概念

OpenSSL 是一个用于实现安全通信的软件包,它由一组密码学函数库组成。它的主要目标是通过使用公开的密码学算法来保护数据的机密性、完整性和身份验证。它支持对称加密、非对称加密、数字签名、证书管理等功能。

2. OpenSSL 原理

OpenSSL 采用了多种密码学算法和协议来实现其安全功能。它支持各种对称密码算法,如 AES、DES 和 Blowfish,用于加密和解密数据。此外,它还支持非对称密码算法,如 RSA 和 DSA,用于生成公钥和私钥,并进行数字签名和验证。OpenSSL 还支持 SSL/TLS 协议,用于在网络通信中建立安全连接。

3. OpenSSL 开发步骤

使用 OpenSSL 进行开发可以分为以下几个步骤:

步骤 1: 安装 OpenSSL
首先,您需要从 OpenSSL 官方网站上下载(免费提供)并安装 OpenSSL 软件包。根据您的操作系统和环境,选择相应的版本进行安装。

步骤 2: 包含头文件
在代码中包含 OpenSSL 的头文件,以便能够使用其中的函数和数据结构。例如,在 C 语言中,可以使用以下语句进行包含:

#include <openssl/ssl.h>

步骤 3: 初始化 OpenSSL
在使用 OpenSSL 之前,需要进行初始化设置。通过调用 SSL_library_init() 函数来初始化 SSL 库。

SSL_library_init();

步骤 4: 创建 SSL 上下文
要建立一个安全连接,需要创建一个 SSL 上下文对象,该对象将存储有关加密和身份验证等设置。您可以使用以下代码片段创建一个 SSL 上下文:

SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method());

步骤 5: 加载证书和私钥
如果您要在服务器端使用 OpenSSL,您需要加载服务器的数字证书和私钥。可以使用以下代码片段进行加载:

SSL_CTX_use_certificate_file(ctx, "server.crt", SSL_FILETYPE_PEM);
SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM);

步骤 6: 建立安全连接
使用 SSL 上下文对象,可以建立与另一端的安全连接。对于服务器端,可以使用以下代码片段:

SSL *ssl = SSL_new(ctx);
SSL_set_fd(ssl, sockfd);
SSL_accept(ssl);

对于客户端,可以使用以下代码片段:

SSL *ssl = SSL_new(ctx);
SSL_set_fd(ssl, sockfd);
SSL_connect(ssl);

步骤 7: 数据传输和处理
一旦安全连接建立成功,就可以在连接上进行数据传输和处理。您可以使用 SSL_read() SSL_write() 函数来读取和写入数据。

char buf[1024];
int len = SSL_read(ssl, buf, sizeof(buf));

步骤 8: 关闭连接
最后,在完成数据传输后,应该关闭 SSL 连接并释放资源。可以使用以下代码片段:

SSL_shutdown(ssl);
SSL_free(ssl);
SSL_CTX_free(ctx);

4. OpenSSL 使用方法

使用 OpenSSL,您可以执行许多加密和安全操作。以下是一些常见的 OpenSSL 使用方法的示例:

  • 对称加密:使用 OpenSSL 命令行工具,您可以加密和解密文件。例如,可以使用以下命令使用 AES 加密一个文件: openssl enc -aes-256-cbc -salt -in <input_file> -out <output_file>

  • 非对称加密:您可以使用 OpenSSL 生成 RSA 密钥对,并使用公钥加密数据,私钥解密数据。例如,可以使用以下命令生成 RSA 密钥对:openssl genpkey -algorithm RSA -out private.pem ,然后使用以下命令加密数据:openssl rsautl -encrypt -pubin -inkey public.pem -in <input_file> -out <output_file>

  • 数字签名:您可以使用 OpenSSL 生成数字签名,并验证签名的有效性。例如,可以使用以下命令生成签名:openssl dgst -sign private.pem -out signature <data_file> ,然后使用以下命令验证签名:openssl dgst -verify public.pem -signature signature <data_file>

5. OpenSSL 应用场景

OpenSSL 在许多领域都有广泛的应用,以下是一些常见的应用场景:

  • 网络安全:OpenSSL 被广泛用于实现 SSL/TLS 协议,以确保在互联网上的数据传输的安全性。它可以用于创建安全的网站、虚拟专用网络(VPN)以及安全电子邮件通信。

  • 证书管理:OpenSSL 可以生成和管理数字证书,用于身份验证和安全通信。它可以用于签署和验证数字证书,并用于创建自签名证书和受信任的证书颁发机构(CA)。

  • 加密工具:OpenSSL 提供了各种加密和解密算法,可以用于保护敏感数据。它可以用于加密文件、密码生成器以及实现端到端的加密通信。

总结:OpenSSL 是一个功能强大的开源软件包,提供了广泛的加密和安全功能。它的概念、原理、开发步骤、使用方法和应用场景都非常丰富。通过使用 OpenSSL,您可以保护您的数据和通信,确保其机密性、完整性和身份验证。无论是在网络通信还是数据安全方面,OpenSSL 都是一个重要的工具和库。

#include <stdio.h>
#include <stdlib.h>
#include <openssl/ssl.h>int main() {// 初始化 OpenSSLSSL_library_init();// 创建 SSL 上下文SSL_CTX *ctx = SSL_CTX_new(SSLv23_client_method());if (ctx == NULL) {printf("Failed to create SSL context.\n");return 1;}// 加载服务器证书if (SSL_CTX_use_certificate_file(ctx, "server.crt", SSL_FILETYPE_PEM) != 1) {printf("Failed to load server certificate.\n");SSL_CTX_free(ctx);return 1;}// 加载服务器私钥if (SSL_CTX_use_PrivateKey_file(ctx, "server.key", SSL_FILETYPE_PEM) != 1) {printf("Failed to load server private key.\n");SSL_CTX_free(ctx);return 1;}// 创建 SSL 对象SSL *ssl = SSL_new(ctx);if (ssl == NULL) {printf("Failed to create SSL object.\n");SSL_CTX_free(ctx);return 1;}// 设置连接套接字int sockfd = socket(AF_INET, SOCK_STREAM, 0);if (sockfd < 0) {printf("Failed to create socket.\n");SSL_free(ssl);SSL_CTX_free(ctx);return 1;}// 连接服务器struct sockaddr_in server_addr;server_addr.sin_family = AF_INET;server_addr.sin_port = htons(443);server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");if (connect(sockfd, (struct sockaddr*)&server_addr, sizeof(server_addr)) < 0) {printf("Failed to connect to server.\n");SSL_free(ssl);SSL_CTX_free(ctx);return 1;}// 将 SSL 对象绑定到连接套接字SSL_set_fd(ssl, sockfd);// 建立 SSL 连接if (SSL_connect(ssl) <= 0) {printf("Failed to establish SSL connection.\n");SSL_free(ssl);SSL_CTX_free(ctx);return 1;}// 发送数据char message[] = "Hello, server!";SSL_write(ssl, message, strlen(message));// 接收数据char buffer[1024];SSL_read(ssl, buffer, sizeof(buffer));printf("Received: %s\n", buffer);// 关闭 SSL 连接SSL_shutdown(ssl);SSL_free(ssl);SSL_CTX_free(ctx);return 0;
}

上面的示例演示了如何使用 OpenSSL 在客户端建立一个安全连接。首先,我们需要初始化 OpenSSL 和创建 SSL 上下文对象。然后,加载服务器的证书和私钥。接下来,我们创建一个 SSL 对象并将其绑定到连接套接字。通过调用SSL_connect() 建立与服务器的安全连接。然后,我们可以使用 SSL_write() 发送数据,使用 SSL_read() 接收数据。最后,我们关闭 SSL 连接并释放资源。

注:这只是一个简单的示例,实际的使用场景可能会更复杂。具体的开发步骤和代码实现可能因应用场景而异。在实际开发过程中,建议参考 OpenSSL 的官方文档和相关资料以获取更详细的信息和指导。

pdf 教程代码

/*************服务端代码**************/
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <errno.h>
#ifndef _WIN32
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#else
#include <winsock2.h>
#include <windows.h>
#endif
#include "pthread.h"
#include <openssl/rsa.h>
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define CERTF "certs/sslservercert.pem"
#define KEYF "certs/sslserverkey.pem"
#define CAFILE "certs/cacert.pem"
pthread_mutex_t mlock = PTHREAD_MUTEX_INITIALIZER;
static pthread_mutex_t *lock_cs;
static long *lock_count;
#define CHK_NULL(x)       \if ((x) == NULL)      \{                     \printf("null\n"); \}
#define CHK_ERR(err, s)   \if ((err) == -1)      \{                     \printf(" -1 \n"); \}
#define CHK_SSL(err)      \if ((err) == -1)      \{                     \printf(" -1 \n"); \}#define CAFILE "certs/cacert.pem"int verify_callback_server(int ok, X509_STORE_CTX *ctx)
{printf("verify_callback_server \n");return ok;
}int SSL_CTX_use_PrivateKey_file_pass(SSL_CTX *ctx, char *filename, char *pass)
{EVP_PKEY *pkey = NULL;BIO *key = NULL;key = BIO_new(BIO_s_file());BIO_read_filename(key, filename);pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, pass);if (pkey == NULL){printf("PEM_read_bio_PrivateKey err");return -1;}if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0){printf("SSL_CTX_use_PrivateKey err\n");return -1;}BIO_free(key);return 1;
}
static int s_server_verify = SSL_VERIFY_NONE;void *thread_main(void *arg)
{SOCKET s, AcceptSocket;WORD wVersionRequested;WSADATA wsaData;struct sockaddr_in service;int err;size_t client_len;SSL_CTX *ctx;SSL *ssl;X509 *client_cert;char *str;char buf[1024];SSL_METHOD *meth;ssl = (SSL *)arg;s = SSL_get_fd(ssl);                                                // SSL_get_fderr = SSL_accept(ssl);                                              // SSL_acceptif (err < 0){printf("ssl accerr\n");return;}printf("SSL connection using %s\n", SSL_get_cipher(ssl));client_cert = SSL_get_peer_certificate(ssl);if (client_cert != NULL){printf("Client certificate:\n");str = X509_NAME_oneline(X509_get_subject_name(client_cert), 0, 0);CHK_NULL(str);printf("\t subject: %s\n", str);OPENSSL_free(str);str = X509_NAME_oneline(X509_get_issuer_name(client_cert), 0, 0);CHK_NULL(str);printf("\t issuer: %s\n", str);OPENSSL_free(str);X509_free(client_cert);}else{printf("Client does not have certificate.\n");}memset(buf, 0, 1024);err = SSL_read(ssl, buf, sizeof(buf) - 1);                          // SSL_readif (err < 0){printf("ssl read err\n");closesocket(s);return;}printf("get : %s\n", buf);
#if 0
buf[err] = '\0';                                                        // SSL_write
err = SSL_write (ssl, "I hear you.", strlen("I hear you.")); CHK_SSL(err);
#endifSSL_free(ssl);closesocket(s);
}pthread_t pthreads_thread_id(void)
{pthread_t ret;ret = pthread_self();return (ret);
}void pthreads_locking_callback(int mode, int type, char *file,int line)
{if (mode & CRYPTO_LOCK){pthread_mutex_lock(&(lock_cs[type]));lock_count[type]++;}else{pthread_mutex_unlock(&(lock_cs[type]));}
}/*
SSL_CTX:数据结构主要用于SSL 握手前的环境准备,设置CA 文件和目录、设置SSL 握手中的证书文件和私钥、设置协议版本以及其他一些SSL 握手时的选项;
SSL:数据结构主要用于SSL 握手以及传送应用数据;
SSL_SESSION:中保存了主密钥、session id、读写加解密钥、读写MAC 密钥等信息;
SSL_CTX 中缓存了所有SSL_SESSION 信息,SSL 中包含SSL_CTX。
*/
int main()
{int err;int i;SOCKET s, AcceptSocket;WORD wVersionRequested;WSADATA wsaData;struct sockaddr_in service;pthread_t pid;size_t client_len;SSL_CTX *ctx;       SSL *ssl;X509 *client_cert;char *str;char buf[1024];SSL_METHOD *meth;SSL_load_error_strings();SSLeay_add_ssl_algorithms();meth = SSLv3_server_method();ctx = SSL_CTX_new(meth);if (!ctx){ERR_print_errors_fp(stderr);exit(2);}if ((!SSL_CTX_load_verify_locations(ctx, CAFILE, NULL)) ||(!SSL_CTX_set_default_verify_paths(ctx))){printf("err\n");exit(1);}if (SSL_CTX_use_certificate_file(ctx, CERTF, SSL_FILETYPE_PEM) <= 0){ERR_print_errors_fp(stderr);exit(3);}if (SSL_CTX_use_PrivateKey_file_pass(ctx, KEYF, "123456") <= 0){ERR_print_errors_fp(stderr);exit(4);}if (!SSL_CTX_check_private_key(ctx)){fprintf(stderr, "Private key does not match the certificate public key\n");exit(5);}s_server_verify = SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT |SSL_VERIFY_CLIENT_ONCE;SSL_CTX_set_verify(ctx, s_server_verify, verify_callback_server);SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file(CAFILE));wVersionRequested = MAKEWORD(2, 2);err = WSAStartup(wVersionRequested, &wsaData);if (err != 0){printf("err\n");return -1;}s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);                          // socket,第一步if (s < 0){return -1;}service.sin_family = AF_INET;service.sin_addr.s_addr = inet_addr("127.0.0.1");service.sin_port = htons(1111);if (bind(s, (SOCKADDR *)&service, sizeof(service)) == SOCKET_ERROR)     // bind{printf("bind() failed.\n");closesocket(s);return -1;}if (listen(s, 1) == SOCKET_ERROR)                                       // listen{printf("Error listening on socket.\n");}printf("recv .....\n");lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));for (i = 0; i < CRYPTO_num_locks(); i++){lock_count[i] = 0;pthread_mutex_init(&(lock_cs[i]), NULL);}// 多线程需要设置的两个回调函数CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);while (1){struct timeval tv;fd_set fdset;tv.tv_sec = 1;tv.tv_usec = 0;FD_ZERO(&fdset);FD_SET(s, &fdset);select(s + 1, &fdset, NULL, NULL, (struct timeval *)&tv);if (FD_ISSET(s, &fdset)){AcceptSocket = accept(s, NULL, NULL);                           // acceptssl = SSL_new(ctx);                                             // SSL_newCHK_NULL(ssl);err = SSL_set_fd(ssl, AcceptSocket);                            // SSL_set_fdif (err > 0){err = pthread_create(&pid, NULL, &thread_main, (void *)ssl);pthread_detach(pid);}elsecontinue;}}SSL_CTX_free(ctx);return 0;
}
/**************客户端代码**************/
#include <stdio.h>
#include <memory.h>
#include <errno.h>
#ifndef _WIN32
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <unistd.h>
#else
#include <windows.h>
#endif
#include "pthread.h"
#include <openssl/crypto.h>
#include <openssl/x509.h>
#include <openssl/pem.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#define MAX_T 1000
#define CLIENTCERT "certs/sslclientcert.pem"
#define CLIENTKEY "certs/sslclientkey.pem"
#define CAFILE "certs/cacert.pem"
static pthread_mutex_t *lock_cs;
static long *lock_count;pthread_t pthreads_thread_id(void)
{pthread_t ret;ret = pthread_self();return (ret);
}
void pthreads_locking_callback(int mode, int type, char *file,int line)
{if (mode & CRYPTO_LOCK){pthread_mutex_lock(&(lock_cs[type]));lock_count[type]++;}else{pthread_mutex_unlock(&(lock_cs[type]));}
}
int verify_callback(int ok, X509_STORE_CTX *ctx)
{printf("verify_callback\n");return ok;
}
int SSL_CTX_use_PrivateKey_file_pass(SSL_CTX *ctx, char *filename, char *pass)
{EVP_PKEY *pkey = NULL;BIO *key = NULL;key = BIO_new(BIO_s_file());BIO_read_filename(key, filename);pkey = PEM_read_bio_PrivateKey(key, NULL, NULL, pass);if (pkey == NULL){printf("PEM_read_bio_PrivateKey err");return -1;}if (SSL_CTX_use_PrivateKey(ctx, pkey) <= 0){printf("SSL_CTX_use_PrivateKey err\n");return -1;}BIO_free(key);return 1;
}void *thread_main(void *arg)
{int err, buflen, read;int sd;SSL_CTX *ctx = (SSL_CTX *)arg;struct sockaddr_in dest_sin;SOCKET sock;PHOSTENT phe;WORD wVersionRequested;WSADATA wsaData;SSL *ssl;X509 *server_cert;char *str;char buf[1024];SSL_METHOD *meth;FILE *fp;wVersionRequested = MAKEWORD(2, 2);err = WSAStartup(wVersionRequested, &wsaData);if (err != 0){printf("WSAStartup err\n");return -1;}sock = socket(AF_INET, SOCK_STREAM, 0);                                 // socket,第一步dest_sin.sin_family = AF_INET;dest_sin.sin_addr.s_addr = inet_addr("127.0.0.1");dest_sin.sin_port = htons(1111);
again:err = connect(sock, (PSOCKADDR)&dest_sin, sizeof(dest_sin));            // connectif (err < 0){Sleep(1);goto again;}ssl = SSL_new(ctx);                                                     // SSL_newif (ssl == NULL){printf("ss new err\n");return;}SSL_set_fd(ssl, sock);                                                  //SSL_connecterr = SSL_connect(ssl);if (err < 0){printf("SSL_connect err\n");return;}printf("SSL connection using %s\n", SSL_get_cipher(ssl));server_cert = SSL_get_peer_certificate(ssl);printf("Server certificate:\n");str = X509_NAME_oneline(X509_get_subject_name(server_cert), 0, 0);printf("\t subject: %s\n", str);OPENSSL_free(str);str = X509_NAME_oneline(X509_get_issuer_name(server_cert), 0, 0);printf("\t issuer: %s\n", str);OPENSSL_free(str);X509_free(server_cert);err = SSL_write(ssl, "Hello World!", strlen("Hello World!"));           // SSL_writeif (err < 0){printf("ssl write err\n");return;}
#if 0
memset(buf,0,ONE_BUF_SIZE);
err = SSL_read (ssl, buf, sizeof(buf) - 1);                                 // SSL_read
if(err<0)
{
printf("ssl read err\n");
return ;
}
buf[err] = '\0';
printf ("Got %d chars:'%s'\n", err, buf);
#endifSSL_shutdown(ssl); /* send SSL/TLS close_notify */SSL_free(ssl);closesocket(sock);
}int main()
{int err, buflen, read;int sd;struct sockaddr_in dest_sin;SOCKET sock;PHOSTENT phe;WORD wVersionRequested;WSADATA wsaData;SSL_CTX *ctx;SSL *ssl;X509 *server_cert;char *str;char buf[1024];SSL_METHOD *meth;int i;pthread_t pid[MAX_T];SSLeay_add_ssl_algorithms();meth = SSLv3_client_method();SSL_load_error_strings();ctx = SSL_CTX_new(meth);if (ctx == NULL){printf("ssl ctx new eer\n");return -1;}if (SSL_CTX_use_certificate_file(ctx, CLIENTCERT, SSL_FILETYPE_PEM) <= 0){ERR_print_errors_fp(stderr);exit(3);}if (SSL_CTX_use_PrivateKey_file_pass(ctx, CLIENTKEY, "123456") <= 0){ERR_print_errors_fp(stderr);exit(4);}lock_cs = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(pthread_mutex_t));lock_count = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(long));for (i = 0; i < CRYPTO_num_locks(); i++){lock_count[i] = 0;pthread_mutex_init(&(lock_cs[i]), NULL);}// 多线程需要设置的两个回调函数CRYPTO_set_id_callback((unsigned long (*)())pthreads_thread_id);CRYPTO_set_locking_callback((void (*)())pthreads_locking_callback);for (i = 0; i < MAX_T; i++){err = pthread_create(&(pid[i]), NULL, &thread_main, (void *)ctx);if (err != 0){printf("pthread_create err\n");continue;}}for (i = 0; i < MAX_T; i++){pthread_join(pid[i], NULL);}SSL_CTX_free(ctx);printf("test ok\n");return 0;
}

相关文章:

OpenSSL 编程示例

参考&#xff1a;深入探索 OpenSSL&#xff1a;概念、原理、开发步骤、使用方法、使用场景及代码示例 地址&#xff1a;https://oneisall.blog.csdn.net/article/details/131489812?spm1001.2014.3001.5502 目录 1. OpenSSL 概念2. OpenSSL 原理3. OpenSSL 开发步骤4. OpenSSL…...

K8S学习指南(17)-k8s核心对象CronJob

文章目录 前言什么是CronJob&#xff1f;示例演示步骤1&#xff1a;创建CronJob步骤2&#xff1a;定义任务模板步骤3&#xff1a;部署CronJob步骤4&#xff1a;监视CronJob的执行 总结 前言 Kubernetes&#xff08;简称K8s&#xff09;是一种用于自动部署、扩展和管理容器化应…...

单片机Freertos入门(二)任务调度的介绍

简介&#xff1a; FreeRTOS支持的任务调度方法有抢占式、协作式、时间片轮转&#xff0c;下面分别来讲解。 1.抢占式调度 抢占式调度&#xff0c;是最高优先级的任务一旦就绪&#xff0c;总能得到CPU的执行权。 高优先级运行时候&#xff0c;低优先级不运行&#xff0c;等待…...

QT----自定义信号和槽

第二天 2.1自定义信号和槽 新建一个Qtclass 自定义信号&#xff1a;返回值是void &#xff0c;只需要声明&#xff0c;不需要实现&#xff0c;可以有参数&#xff0c;可以重载 自定义槽&#xff1a;返回值void &#xff0c;需要声明&#xff0c;也需要实现&#xff0c;可以有…...

【Vue第4章】Vue中的ajax_Vue2

目录 4.1 解决开发环境Ajax跨域问题 4.1.1 解决跨域的三种方法 4.1.2 使用代理服务器 4.1.3 笔记与代码 4.1.3.1 笔记 4.1.3.2 19_src_配置代理服务器 4.2 github用户搜索案例 4.2.1 效果 4.2.2 接口地址 4.2.3 笔记与代码 4.2.3.1 20_src_github搜索案例 4.3 vue项…...

力扣labuladong——一刷day72

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣109. 有序链表转换二叉搜索树二、力扣1382. 将二叉搜索树变平衡 前言 二叉树的递归分为「遍历」和「分解问题」两种思维模式&#xff0c;这道题需要用到…...

Leetcode—509.斐波那契数【简单】

2023每日刷题&#xff08;五十七&#xff09; Leetcode—509.斐波那契数 实现代码 int fib(int n){if(n 0) {return 0;}if(n 1) {return 1;}return fib(n-1) fib(n-2); }运行结果 之后我会持续更新&#xff0c;如果喜欢我的文章&#xff0c;请记得一键三连哦&#xff0c;点…...

山峰个数 - 华为OD统一考试

OD统一考试 分值: 100分 题解: Java / Python / C++ 题目描述 给定一个数组,数组中的每个元素代表该位置的海拔高度。0表示平地,>=1时表示属于某个山峰,山峰的定义为当某个位置的左右海拔均小于自己的海拔时,该位置为山峰。数组起始位置计算时可只满足一边的条件。 …...

38、池化的特征不变性

池化操作有一个比较独特的特性&#xff0c;叫作特征不变性。 很多文章中是这么描述池化的特征不变性的&#xff1a;池化操作的特征不变性&#xff0c;可以提高模型对图片平移、缩放和旋转等变换的鲁棒性。 之前看到这句话的时候&#xff0c;似懂非懂。后来查了一些资料&#…...

051:vue项目webpack打包后查看各个文件大小

第051个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…...

JVM调优:参数(学习笔记)

一、jvm的运行参数 标准参数 -help、-version、-D参数 jvm的标准参数&#xff0c;一般都是很稳定的&#xff0c;在未来的JVM版本中不会改变&#xff0c;可以使用java -help 检索出所有的标准参数。 通过以下命令查看&#xff1a; 命令&#xff1a;java -help 可以看到我们经常…...

MVC Gantt Wrapper:RadiantQ jQuery

The RadiantQ jQuery Gantt Package includes fully functional native MVC Wrappers that let you declaratively and seamlessly configure the Gantt component within your aspx or cshtm pages just like any other MVC extensions. 如果您还没有准备好转向完全基于客户端…...

2019年第八届数学建模国际赛小美赛C题预测通过拥堵路段所需的时间解题全过程文档及程序

2019年第八届数学建模国际赛小美赛 C题 预测通过拥堵路段所需的时间 原题再现&#xff1a; 在导航软件中&#xff0c;行程时间的估计往往是一个重要的功能。现有的导航软件往往通过出租车或安装了该软件的车辆获取实时GPS数据来确定当前的路况。在交通拥堵严重的情况下&#…...

天干地支。

古代中国使用天干地支来记录当前的年份 天干一共有十个&#xff0c;分别为: 甲 (ia) 、乙(yi)、丙(bing) 、丁 (ding) 、成 (wu) 、己(ir) 、庚(geng)辛(xin)、王(ren)、类 (gui)。 分别为:子(zi)、丑 (chu)、寅地支一共有十二个&#xff0c;(yin)、卵 (mao)、辰 (chen) 、已(s…...

RabbitMQ插件详解:rabbitmq_web_stomp【RabbitMQ 六】

欢迎来到我的博客&#xff0c;代码的世界里&#xff0c;每一行都是一个故事 《RabbitMQ Web STOMP&#xff1a;打破界限的消息传递之舞》 前言STOMP协议简介STOMP&#xff08;Simple Text Oriented Messaging Protocol&#xff09;协议简介STOMP与WebSocket的关系 WebSocket和R…...

路由器的转换原理--ENSP实验

目录 一、路由器的工作原理 二、路由表的形成 1、直连路由 2、非直连路由 2.1静态路由 2.2动态路由 三、静态路由和默认路由 1、静态路由 1.1静态路由的缺点 1.2路由的配置--结合ensp实验 2、默认路由--特殊的静态路由 2.1概念 2.2格式 2.3默认路由的配置--ens…...

世界5G大会

会议名称:世界 5G 大会 时间:2023 年 12 月 5 日-12 月 8 日 地点:河南郑州 一、会议简介 世界 5G 大会,是由国务院批准,国家发展改革委、科技部、工 信部与地方政府共同主办,未来移动通信论坛联合属地主管厅局联合 承办,邀请全球友好伙伴共同打造的全球首个 5G 领域…...

FFmpeg-基础组件-AVFrame

本章主要介绍FFmpeg基础组件AVFrame. 文章目录 1.结构体成员2.成员函数AVFrame Host内存的获取 av_frame_get_bufferAVFrame device内存获取av_hwframe_get_buffer&#xff08;&#xff09; 1.结构体成员 我们把所有的代码先粘贴上来&#xff0c;在后边一个一个解释。 typede…...

Vue 组件传参 emit

emit 属性&#xff1a;用于创建自定义事件&#xff0c;接收子组件传递过来的数据。 注意&#xff1a;如果自定义事件的名称&#xff0c;和原生事件的名称一样&#xff0c;那么只会触发自定义事件。 setup 语法糖写法请见&#xff1a;《Vue3 子传父 组件传参 defineEmits》 语…...

Makefile基本指令

语法规则 目标 ... : 依赖 ...命令1命令2. . .1、目标即要生成的文件。如果目标文件的更新时间晚于依赖文件更新时间&#xff0c;则说明依赖文件没有改动&#xff0c;目标文件不需要重新编译。否则会进行重新编译并更新目标文件。 2、默认情况下Makefile的第一个目标为终极目…...

FFmpeg 低延迟同屏方案

引言 在实时互动需求激增的当下&#xff0c;无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作&#xff0c;还是游戏直播的画面实时传输&#xff0c;低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架&#xff0c;凭借其灵活的编解码、数据…...

postgresql|数据库|只读用户的创建和删除(备忘)

CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...

Spring AI 入门:Java 开发者的生成式 AI 实践之路

一、Spring AI 简介 在人工智能技术快速迭代的今天&#xff0c;Spring AI 作为 Spring 生态系统的新生力量&#xff0c;正在成为 Java 开发者拥抱生成式 AI 的最佳选择。该框架通过模块化设计实现了与主流 AI 服务&#xff08;如 OpenAI、Anthropic&#xff09;的无缝对接&…...

让AI看见世界:MCP协议与服务器的工作原理

让AI看见世界&#xff1a;MCP协议与服务器的工作原理 MCP&#xff08;Model Context Protocol&#xff09;是一种创新的通信协议&#xff0c;旨在让大型语言模型能够安全、高效地与外部资源进行交互。在AI技术快速发展的今天&#xff0c;MCP正成为连接AI与现实世界的重要桥梁。…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

处理vxe-table 表尾数据是单独一个接口,表格tableData数据更新后,需要点击两下,表尾才是正确的

修改bug思路&#xff1a; 分别把 tabledata 和 表尾相关数据 console.log() 发现 更新数据先后顺序不对 settimeout延迟查询表格接口 ——测试可行 升级↑&#xff1a;async await 等接口返回后再开始下一个接口查询 ________________________________________________________…...

华为OD机试-最短木板长度-二分法(A卷,100分)

此题是一个最大化最小值的典型例题&#xff0c; 因为搜索范围是有界的&#xff0c;上界最大木板长度补充的全部木料长度&#xff0c;下界最小木板长度&#xff1b; 即left0,right10^6; 我们可以设置一个候选值x(mid)&#xff0c;将木板的长度全部都补充到x&#xff0c;如果成功…...

pycharm 设置环境出错

pycharm 设置环境出错 pycharm 新建项目&#xff0c;设置虚拟环境&#xff0c;出错 pycharm 出错 Cannot open Local Failed to start [powershell.exe, -NoExit, -ExecutionPolicy, Bypass, -File, C:\Program Files\JetBrains\PyCharm 2024.1.3\plugins\terminal\shell-int…...

TJCTF 2025

还以为是天津的。这个比较容易&#xff0c;虽然绕了点弯&#xff0c;可还是把CP AK了&#xff0c;不过我会的别人也会&#xff0c;还是没啥名次。记录一下吧。 Crypto bacon-bits with open(flag.txt) as f: flag f.read().strip() with open(text.txt) as t: text t.read…...

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡

何谓AI编程【02】AI编程官网以优雅草星云智控为例建设实践-完善顶部-建立各项子页-调整排版-优雅草卓伊凡 背景 我们以建设星云智控官网来做AI编程实践&#xff0c;很多人以为AI已经强大到不需要程序员了&#xff0c;其实不是&#xff0c;AI更加需要程序员&#xff0c;普通人…...