【常见开源库的二次开发】基于openssl的加密与解密——Base的编解码(二进制转ascll)(二)

目录:
目录:
一、 Base64概述和应用场景
1.1 概述
1.2 应用场景
二、Base16
2.1 Base16编码
2.2 Base16编解码
三、Base64
四、OpenSSL BIO接☐
4.1 Filter BIOs:
4.2 Source/Sink BIOs:
4.3 应用场景:
4.4 具体使用:
4.5 进行BIO编码:
4.6进行BIO解密:
1.Base64编码(Base64Encode函数)
2. Base64解码(Base64Decode`函数)
3. main函数
一、 Base64概述和应用场景
1.1 概述
Base64是一种编码方式,用于将二进制数据转换为ASCII字符串,以便在只支持文本的媒体上进行存储和传输。它不是一种加密算法,而是一种数据编码技术。Base64编码是一种简单而有效的数据编码方式,它允许二进制数据在文本环境中安全地传输和存储。尽管它不提供安全性(数据在传输过程中可以被读取),但它确保了数据的完整性和可移植性。
1.2 应用场景
邮件编码(base64)
xml或者json存储二进制内容
网页传递数据URL
数据库中以文本形式存放二进制数据
可打印的比特币钱包地址base58 Check(hash校验)
比特币地址bech32(base32)
二、Base16
2.1 Base16编码
Base16是一种编码方法,它使用16个可打印的ASCII字符来表示二进制数据。这些字符包括数字0到9和字母A到F。每个字符代表4个二进制位,因此Base16有时也称为十六进制编码。

在Base16编码过程中,首先将原始数据(如文本或文件)转换成二进制形式。对于ASCII编码字符,这一步直接涉及将每个字符转换为其对应的8位二进制值。对于UTF-8或其他编码,可能涉及更复杂的转换过程。
接下来,将得到的二进制串按照每4位一组进行切分。由于每组4位可以对应一个0到15之间的十进制数,这个数可以直接映射到上述提到的16个字符之一。例如,二进制组0101对应十进制数5,按Base16编码转换成字符5;二进制组1001对应十进制数9,转换成字符9;二进制组1010对应十进制数10,转换成字符A,依此类推。

由于Base16使用4位二进制表示一个字符,一个字节(8位)被编码为两个Base16字符。因此,Base16编码后的数据大小是原始数据大小的两倍。
#include <iostream>using namespace std;
// 定义一个静态的常量字符数组,用于Base16编码的字符映射表
static const char BASE16_ENC_TAB[] = "123456789ABCDEF";// 函数:将输入的原始数据按照Base16编码规则编码到输出字符串中
// 参数:in - 指向原始数据的指针;size - 原始数据的字节数;out - 指向输出编码字符串的指针
// 返回值:编码后的字符串长度,即原始数据长度的两倍
int Base16Encode(const unsigned char* in, int size, char* out)
{// 遍历原始数据的每个字节for (int i = 0; i < size; i++){// 将当前字节的高四位右移四位,得到高四位的值char h = in[i] >> 4; // 例如:二进制1000 0001通过移位变为0000 1000// 将当前字节的低四位与0x0F进行与操作,得到低四位的值char l = in[i] & 0x0F; // 例如:二进制0000 1111与0x0F与操作后得到0000 0001// 根据高四位的值,在编码表中查找对应的字符,并存入输出字符串out[i * 2] = BASE16_ENC_TAB[h]; // 映射高四位到编码表对应的字符// 根据低四位的值,在编码表中查找对应的字符,并存入输出字符串out[i * 2 + 1] = BASE16_ENC_TAB[l]; // 映射低四位到编码表对应的字符}// 返回编码后的字符串长度,即原始数据长度的两倍return size * 2;
}int main(int argc, char* argv[])
{cout << "测试Base16编码" << endl;// 定义待编码的原始数据const unsigned char data[] = "测试base16";// 获取原始数据的字节长度int len = sizeof(data) - 1; // 减1是因为sizeof包含了结尾的'\0'字符// 定义足够大的输出数组来存放编码后的字符串char out1[1024] = { 0 };// 打印原始数据cout << "原始数据: " << data << endl;// 调用Base16编码函数int re = Base16Encode(data, len, out1);// 打印编码后的字符串及其长度cout << "编码后长度: " << re << ", 编码结果: " << out1 << endl;return 0;
}
(1) 定义了一个静态常量字符数组`BASE16_ENC_TAB`,包含了Base16编码所需的字符('0'-'9'和'A'-'F')。
(2)Base16Encode`函数接收三个参数:指向原始数据的指针`in`,原始数据的字节数`size`,以及指向输出编码字符串的指针`out`。
(3) 在`Base16Encode`函数中,使用一个循环遍历输入数据的每个字节。对于每个字节,进行以下操作:
将字节的高四位右移四位,得到一个0到15之间的值,这个值对应于该字节的高四位。
将字节与0x0F进行位与操作,得到一个0到15之间的值,这个值对应于该字节的低四位。
使用这两个值作为索引,在`BASE16_ENC_TAB`数组中查找对应的字符,并将这些字符分别存储到输出字符串的相应位置。
(4)循环结束后,返回编码后的字符串长度,即原始数据长度的两倍。
(5)在`main`函数中,定义了一个待编码的字符串`data`,计算其长度(不包括结尾的空字符'\0'),并声明了一个足够大的字符数组`out1`来存储编码后的字符串。
(6)`main`函数打印出原始数据,调用`Base16Encode`函数进行编码,并打印出编码后的字符串及其长度。

代码定义了一个Base16Encode函数,用于将输入的原始数据按照Base16编码规则编码到输出字符串中,并在main函数中进行了测试。sizeof(data)包含了字符串结尾的空字符\0,所以在计算长度时应该减去1,否则会将空字符也进行编码。
2.2 Base16编解码
Base16(或称为十六进制)编码是一种将二进制数据转换为一种使用16个可打印字符(0-9和A-F)表示的方法。Base16编码的解码过程是将编码后的字符串转换回原始的二进制数。
实现了Base16编码和解码的功能。
#include <iostream>
// 引入iostream库,用于输入输出操作using namespace std;
// 使用std命名空间,避免在代码中重复写std::前缀// 定义一个静态的常量字符数组,用于Base16编码的字符映射表
static const char BASE16_ENC_TAB[] = "0123456789ABCDEF"; // 包含16进制编码的字符,从0到Fstatic const char BASE16_DEC_TAB[128] = {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ASCII码0-15,非16进制字符映射为-1-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ASCII码16-31,非16进制字符映射为-1-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ASCII码32-47,非16进制字符映射为-10, 1, 2, 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, -1, -1, -1, // ASCII码48-57,对应0-9-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ASCII码65-70,对应A-F-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ASCII码71-76,非16进制字符映射为-1-1, 10, 11, 12, 13, 14, 15, -1, -1, -1, -1, -1, -1, -1, -1, -1, // ASCII码91-96,对应a-f-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 // ASCII码97-102,非16进制字符映射为-1
}; // 正确填充解码表,非16进制字符映射为-1// 函数:将输入的原始数据按照Base16编码规则编码到输出字符串中
int Base16Encode(const unsigned char* in, int size, char* out) {for (int i = 0; i < size; i++) {char h = in[i] >> 4; // 获取字节的高4位char l = in[i] & 0x0F; // 获取字节的低4位out[i * 2] = BASE16_ENC_TAB[h]; // 将高4位转换为对应的16进制字符out[i * 2 + 1] = BASE16_ENC_TAB[l]; // 将低4位转换为对应的16进制字符}return size * 2; // 返回编码后的长度,是输入长度的两倍
}// 函数:将Base16编码的字符串解码回原始数据
int Base16Decode(const string& in, char* out) {for (int i = 0; i < in.size(); i += 2) { // 以2个字符为一组进行解码unsigned char h = BASE16_DEC_TAB[static_cast<unsigned char>(in[i])]; // 获取高4位unsigned char l = BASE16_DEC_TAB[static_cast<unsigned char>(in[i + 1])]; // 获取低4位out[i / 2] = (h << 4) | l; // 将高4位和低4位合并成原始字节}return in.size() / 2; // 返回解码后的长度,与输入长度相同
}int main(int argc, char* argv[]) {cout << "测试Base16编码" << endl;const unsigned char data[] = "测试base16编码";int len = sizeof(data) - 1;char out1[1024] = { 0 };unsigned char out2[1024] = { 0 };cout << "原始数据: " << data << endl;int encodedLength = Base16Encode(data, len, out1);cout << "编码后长度: " << encodedLength << ", 编码结果: " << out1 << endl;int decodedLength = Base16Decode(out1, reinterpret_cast<char*>(out2));cout << "解码后长度: " << decodedLength << ", 解码结果: " << out2 << endl;return 0;
}
1. 字符映射表:
BASE16_ENC_TAB 是一个包含16进制编码字符的静态常量字符数组,从'0'到'F'
BASE16_DEC_TAB 是一个静态常量字符数组,用于将ASCII码转换为对应的16进制数值。数组中索引0-15对应ASCII码0-9和A-F,其他索引为-1,表示不是16进制字符。
2. Base16Encode函数:
接受三个参数:输入数据的指针in,输入数据的大小size,输出字符串的指针out。
循环遍历输入数据的每个字节,提取高4位和低4位。
使用高4位和低4位索引`BASE16_ENC_TAB`数组,获取对应的16进制字符。
将两个字符依次写入输出字符串的相应位置。
函数返回编码后的长度,即输入长度的两倍。
3. Base16Decode函数:
接受两个参数:Base16编码的字符串`in`和输出数据的指针out。
以两个字符为一组进行解码,因为Base16编码是将每个字节转换为两个字符。
使用输入字符串的每个字符索引BASE16_DEC_TAB数组,获取对应的16进制数值。
将高4位和低4位合并成一个字节,写入输出数据。
函数返回解码后的长度,即输入长度的一半。
4. main函数:
定义测试数据data,它是要编码和解码的字符串。
定义输出缓冲区out1用于存储编码后的字符串,以及`out2`用于存储解码后的数据。
打印原始数据。
调用Base16Encode函数编码数据,并打印编码后的长度和结果。
调用Base16Decode函数解码数据,并打印解码后的长度和结果。

通过定义字符映射表和实现编码和解码函数,实现了对字符串进行Base16编码和解码的功能。在`main`函数中,通过示例数据展示了如何使用这些函数。
三、Base64

1. 分组处理:Base64编码将每3个字节的二进制数据(24位)作为一组进行处理。

2. 转换:将这3个字节的24位分成4组,每组6位。每组的6位二进制数转换成对应的4位Base64字符。

3. 补齐:如果原始数据不是3的倍数,那么在最后可能会剩下1个或2个字节。为了将这些数据也能编码,Base64会在编码后的字符串末尾添加'='字符。如果剩余1个字节,就会添加一个'=';如果剩余2个字节,就会添加两个'='。
四、OpenSSL BIO接☐
penSSL BIO(Basic I/O)是OpenSSL库中用于抽象I/O操作的一个组件。BIO提供了多种接口来控制不同类型的I/O操作
4.1 Filter BIOs:
这些BIOs用于在数据从一个BIO流向另一个BIO的过程中进行转换或过滤。
BIO_f_base64():用于Base64编码和解码。BIO_f_cipher():用于加密和解密。BIO_f_md5():用于MD5散列。BIO_f_md4():用于MD4散列。BIO_f_sha1():用于SHA-1散列。BIO_f_sm3():用于SM3散列。BIO_f_sign():用于签名。BIO_f_verify():用于验证签名。BIO_f_negotiate():用于TLS/SSL协商。BIO_f_buffer():用于缓冲。
4.2 Source/Sink BIOs:
这些BIOs是数据源或接收器
BIO_new(BIO_s_mem()):创建一个内存BIO,用于存储数据。BIO_new(BIO_s_file()):创建一个文件BIO,用于文件读写。BIO_new(BIO_s_socket()):创建一个套接字BIO,用于网络通信。BIO_new(BIO_s_fd()):创建一个文件描述符BIO。BIO_new(BIO_s_open()):创建一个用于打开文件的BIO。BIO_new(BIO_s_mem()):创建一个内存BIO。BIO_new(BIO_s_connect()):创建一个用于连接的BIO。BIO_new(BIO_s_accept()):创建一个用于接受连接的BIO。
4.3 应用场景:
- BIOs常用于构建复杂的I/O操作,如加密通信、数据转换等。
- 在TLS/SSL通信中,BIOs用于封装底层的I/O操作,如读写数据。
4.4 具体使用:
BIO_new():用于创建一个新的BIO对象。- 数据源BIO,例如
BIO_new(BIO_s_mem()),创建一个内存BIO。- 过滤BIO,例如
BIO_new(BIO_f_base64()),创建一个Base64编码和解码的过滤BIO。- 创建BIO链,例如
BIO_push(b64_bio, mem_bio),将Base64过滤BIO和内存BIO连接起来。BIO_write():用于向BIO写入数据。当使用Base64过滤BIO时,数据会被编码。BIO_read_ex():用于从BIO读取数据。当使用Base64过滤BIO时,数据会被解码。
4.5 进行BIO编码:
通过使用OpenSSL的BIO链表和Base64编码过滤器,将输入数据编码为Base64格式,并将结果输出到控制台。主要思路是利用OpenSSL库提供的功能,通过BIO链表处理编码过程,最后将编码后的数据存储并输出。
#include <iostream>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <cstring> using namespace std;int Base64Encode(const unsigned char* in, int len, char* out_base64)
{if (!in || len <= 0 || !out_base64)return 0;// 内存源auto mem_bio = BIO_new(BIO_s_mem());if (!mem_bio) return 0;// base64 filterauto b64_bio = BIO_new(BIO_f_base64());if (!b64_bio){BIO_free(mem_bio);return 0;}// 形成BIO链表// b64-memBIO_push(b64_bio, mem_bio);// 写入到base64 filter 进行编码,结果会传递到链表的下一个节点// 到mem中读取结果(从链表头部,代表了整个链表)int re = BIO_write(b64_bio, in, len);if (re < 0){// 清空整个链表节点BIO_free_all(b64_bio);return 0;}// 刷新缓存,写入链表的memBIO_flush(b64_bio);int outsize = 0;// 从链表源内存读取BUF_MEM* p_data = NULL;BIO_get_mem_ptr(b64_bio, &p_data);if (p_data){// 确保输出数组足够大if (p_data->length < len * 4 / 3 + 1){BIO_free_all(b64_bio);return 0;}memcpy(out_base64, p_data->data, p_data->length);outsize = p_data->length;}BIO_free_all(b64_bio);return outsize;
}int main(int argc, char *argv[])
{cout << "The openssl BIO base64!" << endl;unsigned char data[] = "测试Base64数据";int len = sizeof(data);char out[len * 4 / 3 + 1]; // 基于最大编码长度分配内存int encoded_len = Base64Encode(data, len, out);if (encoded_len > 0){out[encoded_len] = '\0'; // 确保字符串以null终止cout << out << endl;}getchar();return 0;
}
1. 包含必要的头文件:
<iostream>:用于输入输出流。
<openssl/evp.h>:用于加密和编码操作。
<openssl/buffer.h>:用于缓冲区操作。
<cstring>:用于字符串操作。
2. 命名空间声明:
使用`using namespace std;`使得`std`命名空间下的元素可以直接使用,无需前缀。
3. 定义Base64编码函数`Base64Encode:
函数接收三个参数:输入数据指针`in`,输入数据长度`len`,输出Base64编码数据指针out_base64。
进行参数有效性检查,如果输入无效,则返回0。
创建一个`BIO`(BASIC I/O)对象`mem_bio`,用于内存操作。
创建一个`BIO`对象`b64_bio`,用于Base64编码。
将`b64_bio`连接到`mem_bio`后面,形成BIO链表,以便将编码后的数据写入内存。
使用`BIO_write`将输入数据写入到`b64_bio`。
使用`BIO_flush`将缓存中的数据写入到内存中。
获取编码后的数据长度,并确保输出数组足够大。
将编码后的数据复制到输出数组中。
释放BIO资源,并返回编码后的数据长度。
4. 主函数main:
打印一个信息字符串。
定义一个要编码的字符数组`data`。
调用`Base64Encode`函数进行编码。
如果编码成功,将编码后的数据输出到控制台。
等待用户按键,然后退出程序。

4.6进行BIO解密:
使用了OpenSSL库中的BIO(块I/O)抽象,它提供了一种灵活的方式来处理不同类型的I/O操作,包括加密和编码操作。通过将Base64编码和解码功能封装在BIO链表中。
#include <iostream>
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>
#include <cstring>using namespace std;int Base64Encode(const unsigned char* in, int len, char* out_base64)
{if (!in || len <= 0 || !out_base64)return 0;// 内存源auto mem_bio = BIO_new(BIO_s_mem());if (!mem_bio) return 0;// base64 filterauto b64_bio = BIO_new(BIO_f_base64());if (!b64_bio){BIO_free(mem_bio);return 0;}// 形成BIO链表// b64-memBIO_push(b64_bio, mem_bio);// 写入到base64 filter 进行编码,结果会传递到链表的下一个节点// 到mem中读取结果(从链表头部,代表了整个链表)//write为编码 3字节-》4字节,不足3字节补充0和=int re = BIO_write(b64_bio, in, len);if (re < 0){// 清空整个链表节点BIO_free_all(b64_bio);return 0;}// 刷新缓存,写入链表的memBIO_flush(b64_bio);int outsize = 0;// 从链表源内存读取BUF_MEM* p_data = NULL;BIO_get_mem_ptr(b64_bio, &p_data);if (p_data){// 确保输出数组足够大if (p_data->length < len * 4 / 3 + 1){BIO_free_all(b64_bio);return 0;}memcpy(out_base64, p_data->data, p_data->length);outsize = p_data->length;}BIO_free_all(b64_bio);return outsize;
}int Base64Decode(const char* in, int len, unsigned char* out_data)
{if (!in || len <= 0 || !out_data)return 0;// 内存源:密文BIO* mem_bio = BIO_new_mem_buf(in, len);if (!mem_bio)return 0;// base64过滤器BIO* b64_bio = BIO_new(BIO_f_base64());if (!b64_bio){BIO_free(mem_bio);return 0;}// 形成BIO链BIO_push(b64_bio, mem_bio);// 读取 解码// read为解码 4字节 -> 3字节size_t size = 0;BIO_read_ex(b64_bio, out_data, len, &size);BIO_free_all(b64_bio);// 将解码后的字节转换为字符串string decoded_string((char*)out_data, size);// 打印解码后的字符串,以便于检查cout << "Decoded data: " << decoded_string << endl;return size;
}int main(int argc, char* argv[]) {cout << "The openssl BIO base64!" << endl;unsigned char data[] = "测试Base数据的结果";int len = sizeof(data);char out[len * 4 / 3 + 1]; // 基于最大编码长度分配内存unsigned char out2[len * 4 / 3 + 1]; // 声明变量out2int encoded_len;cout << "source: " << data << endl << endl;encoded_len = Base64Encode(data, len, out);cout << "encode: ";if (encoded_len > 0) {out[encoded_len] = '\0'; // 确保字符串以null终止cout << out << endl;}encoded_len = Base64Decode(out, encoded_len, out2); // 使用编码后的长度cout << endl << "Decoded data: ";cout << (const char*)out2 << endl;getchar();return 0;
}
实现了两个主要功能:Base64编码和Base64解码。
1.Base64编码(Base64Encode函数)
(1). 输入验证:首先检查输入参数是否有效,包括输入数据指针、长度和输出缓冲区指针。
(2). BIO链表初始化:
创建一个内存BIO(`BIO_s_mem`),用于临时存储编码数据。
创建一个Base64过滤器BIO(`BIO_f_base64`),用于执行Base64编码。
(3). 形成BIO链表:将Base64过滤器BIO插入到内存BIO的前面,形成链表。
(4). 写入数据:使用`BIO_write`函数将输入数据写入Base64过滤器BIO。
(5). 刷新缓存:使用`BIO_flush`函数刷新缓存,确保所有数据都被编码。
(6). 读取编码数据:
使用`BIO_get_mem_ptr`函数获取内存BIO中的数据。
检查输出缓冲区是否足够大以存储编码数据。
使用`memcpy`将编码数据复制到输出缓冲区。
(7). 清理:释放所有BIO资源。
2. Base64解码(Base64Decode`函数)
(1). 输入验证:同样检查输入参数是否有效。
(2). BIO链表初始化:
创建一个内存BIO,用于存储输入的Base64编码数据。
创建一个Base64过滤器BIO,用于执行Base64解码。
(3). 形成BIO链表:将Base64过滤器BIO插入到内存BIO的前面。
(4). 读取和解码数据:
使用`BIO_read_ex`函数从Base64过滤器BIO中读取和解码数据。
输出解码后的数据到用户提供的缓冲区。
(5). 清理:释放所有BIO资源。
3. main函数
(1). 打印欢迎信息。
(2). 编码数据:
调用`Base64Encode`函数进行编码。
输出编码后的Base64字符串。
(3). 解码数据:
调用`Base64Decode`函数进行解码。
输出解码后的原始数据。
(4). 等待用户输入,以便用户可以看到输出并手动关闭程序。

到此我们就算对Base64的编解码都实现其功能
相关文章:
【常见开源库的二次开发】基于openssl的加密与解密——Base的编解码(二进制转ascll)(二)
目录: 目录: 一、 Base64概述和应用场景 1.1 概述 1.2 应用场景 二、Base16 2.1 Base16编码 2.2 Base16编解码 三、Base64 四、OpenSSL BIO接☐ 4.1 Filter BIOs: 4.2 Source/Sink BIOs: 4.3 应用场景: 4.4 具体使用&…...
ssrf复习(及ctfshow351-360)
1. SSRF 概述 服务器会根据用户提交的URL发送一个HTTP请求。使用用户指定的URL,Web应用可以获取图片或者文件资源等。典型的例子是百度识图功能。 如果没有对用户提交URL和远端服务器所返回的信息做合适的验证或过滤,就有可能存在“请求伪造"的缺陷…...
请求通过Spring Cloud Gateway 503
最近想处理一个通用的网关服务。 但是我在处理好所有配置的时候发现,网络请求过网关的时候,一直503,我所有的配置都没问题。 环境: JDK: 17 Spring Cloud: 2023.0.2 在 Spring Cloud Gateway 的早期版本中ÿ…...
C++代码_让室友坑我
引子 今天古文波在外地上C集训营,结果却被一起学习的室友坑了。啊,好气,我要报复室友。 所以,我写出了死亡代码。 如果你也想报复某些人,可以看下去。 代码构造: 头文件 想要使用一些函数,如…...
AG32 的MCU与FPGA的主频可以达到568MHz吗
Customers: AG32/ AGRV2K 这个芯片主频和定时器最高速度是多少?用户期望 CPLD计时器功能0.1ns以下。 AGM RE: CPLD做不到 0.1ns的速率,这个需要10G以上的时钟。 那AGRV2K最高多少MHz呢? 一般200MHZ比较容易实现。 进一步说明࿱…...
怎样减少视频的容量 怎样减少视频内存保持清晰度
在数字媒体时代,视频内容已经成为人们日常交流和信息传递的重要方式。然而,视频往往占用大量存储空间,给我们的设备带来不小的负担。如何在不损失视频质量的前提下,减少视频文件的大小呢?本文将为你揭秘几个实用的技巧…...
谈一谈一条SQL的查询、更新语句究竟是如何执行的?
文章目录 理解执行流程衍生知识redo logbinlog 本篇文章是基于《MySQL45讲》来写的个人理解与感悟。 理解 先看下图: 上一篇文章我们讨论了一条SQL查询语句的执行流程,并介绍了执行过程中涉及的处理模块。 回顾一下: 大体来说,…...
自动驾驶AVM环视算法–全景和标定全功能算法实现和exe测试demo
参考:全景和标定全功能算法实现和exe测试demo-金书世界 1、测试环境 opencv310vs2022 2、使用的编程语言 c和c 3、测试的demo的获取 更新:测试的exe程序,无需解压码就可以体验算法测试效果 百度网盘: 链接:http…...
【Docker 系列】学习路线
学习基本概念: 了解容器化与虚拟化的区别了解Docker的基本概念、术语和架构 安装Docker: 根据所使用的操作系统,安装Docker Desktop(Windows、macOS)或Docker Engine(Linux) Docker镜像…...
蓝色系信息工作室建站网站源码系统 带模版手机端 带完整的源代码包以及搭建部署教程
系统概述 信息工作室建站网站源码系统是一款专为追求高效、灵活与个性化建站需求的用户设计的综合性平台。该系统不仅提供了丰富的网站构建模块和预设模版,还支持手机端自适应布局,确保网站在不同设备上都能展现出最佳效果。此外,系统附带完…...
什么是带宽限制,如何影响服务器数据传输?
什么是带宽限制? 带宽限制是指网络连接中的数据传输速率上限,通常以每秒传输的数据量(比特或字节)来衡量。例如,一个服务器的带宽限制为100 Mbps,意味着它在理想情况下每秒最多能传输100兆比特的数据。带宽限制由网络服务提供商或数据中心设…...
RISC-V在线反汇编工具
RISC-V在线反汇编工具: https://luplab.gitlab.io/rvcodecjs/#q34179073&abifalse&isaAUTO 不过,似乎,只支持RV32I、RV64I、RV128I指令集:...
从零手写实现 nginx-32-load balance 负载均衡算法 java 实现
前言 大家好,我是老马。很高兴遇到你。 我们为 java 开发者实现了 java 版本的 nginx https://github.com/houbb/nginx4j 如果你想知道 servlet 如何处理的,可以参考我的另一个项目: 手写从零实现简易版 tomcat minicat 手写 nginx 系列 …...
基于STC89C51单片机的烟雾报警器设计(煤气火灾检测报警)(含文档、源码与proteus仿真,以及系统详细介绍)
本篇文章论述的是基于STC89C51单片机的烟雾报警器设计的详情介绍,如果对您有帮助的话,还请关注一下哦,如果有资源方面的需要可以联系我。 目录 摘要 原理图 实物图 仿真图 元件清单 代码 系统论文 资源下载 摘要 随着现代家庭用火、…...
SpringBoot整合阿里云RocketMQ对接,商业版
1.需要阿里云开通商业版RocketMQ 普通消息新建普通主题,普通组,延迟消息新建延迟消息主题,延迟消息组 2.结构目录 3.引入依赖 <!--阿里云RocketMq整合--><dependency><groupId>com.aliyun.openservices</groupId><artifactId>ons-client</…...
modbus slave 设备通过 网关thingsboard-gateway 将数据上传到thingsboard云平台
搭建thingsboard物联网云平台花了大量时间,从小白到最后搭建成功,折磨了好几天,也感谢网友的帮助,提供了思路最终成功搞定,特此记录。 一、thingsboard环境搭建(Ubuntu20.04LTS) 参考官方文档&a…...
安全防御:智能选路
目录 一、智能选路 1.1 就近选路 1.2 策略路由 1.3 虚拟系统---VRF 二、全局选路策略 1,基于链路带宽进行负载分担 2,基于链路质量进行负载分担 3,基于链路权重的负载分担 4,根据链路优先级的主备备份 DNS透明代理 一、…...
Gitee使用教程2-克隆仓库(下载项目)并推送更新项目
一、下载 Gitee 仓库 1、点击克隆-复制代码 2、打开Git Bash 并输入复制的代码 下载好后,找不到文件在哪的可以输入 pwd 找到仓库路径 二、推送更新 Gitee 项目 1、打开 Git Bash 用 cd 命令进入你的仓库(我的仓库名为book) 2、添加文件到 …...
Postfix+Dovecot+Roundcube开源邮件系统搭建系列1-2:系统搭建目标+MariaDB数据库配置(MySQL)
1. 系统搭建目标 通过本系列文章,最终可以部署一套提供如下服务的邮件系统: SMTP服务:由Postfix提供,监听25、465、587端口。POP3服务:由Dovecot提供,监听110、995端口。IMAP服务:由Dovecot提…...
Flower花所比特币交易及交易费用科普
在加密货币交易中,选择一个可靠的平台至关重要。Flower花所通过提供比特币交易服务脱颖而出。本文将介绍在Flower花所进行比特币交易的基础知识及其交易费用。 什么是Flower花所? Flower花所是一家加密货币交易平台,为新手和资深交易者提供…...
vscode里如何用git
打开vs终端执行如下: 1 初始化 Git 仓库(如果尚未初始化) git init 2 添加文件到 Git 仓库 git add . 3 使用 git commit 命令来提交你的更改。确保在提交时加上一个有用的消息。 git commit -m "备注信息" 4 …...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
微信小程序 - 手机震动
一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注:文档 https://developers.weixin.qq…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
Module Federation 和 Native Federation 的比较
前言 Module Federation 是 Webpack 5 引入的微前端架构方案,允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...
Mysql中select查询语句的执行过程
目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析(Parser) 2.4、执行sql 1. 预处理(Preprocessor) 2. 查询优化器(Optimizer) 3. 执行器…...
打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
SQL Server 触发器调用存储过程实现发送 HTTP 请求
文章目录 需求分析解决第 1 步:前置条件,启用 OLE 自动化方式 1:使用 SQL 实现启用 OLE 自动化方式 2:Sql Server 2005启动OLE自动化方式 3:Sql Server 2008启动OLE自动化第 2 步:创建存储过程第 3 步:创建触发器扩展 - 如何调试?第 1 步:登录 SQL Server 2008第 2 步…...
AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)
Name:3ddown Serial:FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名:Axure 序列号:8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...
