【智能家居】七、人脸识别 翔云平台编程使用(编译openSSL支持libcurl的https访问、安装SSL依赖库openSSL)

一、翔云 人工智能开放平台

  • API文档
  • 开发示例下载

二、编译openSSL支持libcurl的https访问

  • 安装SSL依赖库openSSL(使用工具wget)
  • libcurl库重新配置,编译,安装
  • 运行(运行需添加动态库为环境变量)

三、编程实现人脸识别
四、Base64编码
五、RGB颜色模型(用于表示图像中的颜色信息)
六、BMP 图像以像素矩阵的形式存储
七、Base64数据格式转换
八、加入图片base64编码
九、人脸识别完整代码及功能点实现现象

一、翔云 人工智能开放平台

翔云 人工智能开放平台
在这里插入图片描述
下面通过人工智能OCR识别平台翔云的使用,掌握调库调API开发的一般步骤,其他的平台也基本类似。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

API文档

在这里插入图片描述

开发示例下载

在这里插入图片描述

C++示例代码

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

strPostData.Format(_T("img=%s&key=%s&secret=%s&typeId=%d&format=xml"),strImageBase64,strKey,strSecret,nTypeID);

Java示例代码

java大多直接调库,非常简洁,这也是它开发效率高的原因之一。
在这里插入图片描述
在这里插入图片描述

二、编译openSSL支持libcurl的https访问

在这里插入图片描述
 那是因为在编译libcurl库的时候,由于翔云接口是https:开头的,需要选择支持SSL。

./configure --with -ssl

 我们访问的接口是https开头的,要进行身份验证和数据加密的,体现在我们的key和secret。

 那我们就要回到/curl-7.71.1路径下,删除rm _install -rf上次编译出来的文件夹,重新编译支持SSL的库。由/docs/INSTALL.md我们可以得知要想支持SSL,就得./configure --with-ssl

chmod +x configure
sudo ./configure --prefix=$PWD/_install --with-ssl

编译错误

cheking for SSL_connect in -lssl... (cached)no no
configure:error:openSSL libs and/or directories were not found where specified!

安装SSL依赖库openSSL(使用工具wget)

 想要支持SSL必须要有依赖库,需要系统中已经安装好了SSL。

 我们需要安装openSSL.tar

利用linux的开源工具下载wget是Linux中的一个下载文件的工具,wget是在Linux下开发的开放源代码的软件。

百度搜索技巧:wget openSSL.tar

wget https://www.openssl.org/source/openssl-1.1.1a.tar.gz
tar xvf openssl-1.1.1a.tar.gz

进入文件夹,直接去看他的INSTALL。

 为了避免到时候编译这个curl又要去配置SSL这个库,我们直接把SSL安装到默认的系统位置去(一般默认是在/usr/local底下),所以不指定安装路径了,直接在/openssl-1.1.1a路径下,配置

./config
make
sudo make install

在这里插入图片描述
在这里插入图片描述

安装配置openssl库时间比较长建议网络稳定ssh建议用MobaXtermvscodessh安装可能会掉
加 sudo就肯定安装在了 usr/local 中,非工作目录无权限

libcurl库重新配置,编译,安装

回到/curl-7.71.1/目录下重新进行配置:

chmod +x configure
sudo ./configure --prefix=$PWD/_install --with-ssl
sudo make 
make install

在这里插入图片描述
在这里插入图片描述

运行(运行需添加动态库为环境变量)

生成了可执行文件./a.out直接运行可能会报错(我没有报错,可能是我用的Ubuntu22.04)。

原因是运行时要链接动态库,没有添加环境变量

cd /home/orangepi/curl-7.71.1/_install/lib
export LD_LIBRARY_PATH=/home/orangepi/curl-7.71.1/_install/lib

永久有效,配置环境变量,要改配置文件

在Linux系统上,如果你希望将libcurl库的路径添加到永久环境变量中,你可以编辑shell配置文件,例如bash的.bashrc文件。以下是在bash shell中将libcurl库路径添加到LD_LIBRARY_PATH环境变量的步骤:

  1. 打开.bashrc文件,可以使用文本编辑器如nanovimgedit等。

    nano ~/.bashrc
    
  2. 在文件的末尾添加以下行,其中/path/to/libcurl是libcurl库的实际路径。

    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/path/to/libcurl
    

    替换/path/to/libcurl为libcurl库的实际路径。

  3. 保存并关闭文件。

  4. 使更改生效。可以通过运行以下命令重新加载.bashrc文件:

    source ~/.bashrc
    

    或者,你可以注销并重新登录。

现在,libcurl库的路径将在每次启动新shell时自动添加到LD_LIBRARY_PATH中。这确保了libcurl库在系统范围内可用。请注意,这只对当前用户生效。如果你希望所有用户都能访问libcurl库,你可能需要将环境变量设置添加到/etc/environment文件中,这需要超级用户权限。

echo $PATH 	// 获得当前环境变量的值
pwd			// 获得当前路径

修改工作目录下的 .bashrc 隐藏文件,配置命令终端

vi /home/orangepi/.bashrc 

在文件最后一行加入:

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/orangepi/curl-7.71.1/_install/lib
source /home/orangepi/.bashrc 加载配置文件,马上生效配置。

在这里插入图片描述

三、编程实现人脸识别

翔云人脸识别API文档

在这里插入图片描述

ocr.c

#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
#include <stdlib.h>

// 定义bool类型和常量
typedef unsigned int bool; // 数据类型别名用typedef
#define true 1
#define false 0

// 回调函数,读取从OCR后台返回的数据  前面打开百度的例子是将内容读取到本地文件fd里面
size_t readData(void *ptr, size_t size, size_t nmemb, void *stream)
{
        // 在这里处理返回的数据,例如保存到文件或进行其他处理
        char buf[1024] = {'\0'};
        strncpy(buf, ptr, 1024);
        printf("============================= get data ===========================\n");
        printf("%s\n", buf);

        return size * nmemb;
}

// 根据文档,接口调用方法为post请求
bool postUrl()
{
        CURL *curl;
        CURLcode res;
        char *postString = NULL; // 空指针,要开辟空间

        // 根据翔云平台的接口要求  分开定义,然后字符串拼接
        char *img1 = NULL; // 图片base64流
        char *img2 = NULL;
        char *key = "JFD5c1iBh9LVqPkkZMxxxx";
        char *secret = "76f444813fc945bd9543e4d7e086xxxx";
        int typeId = 21;
        char *format = "xml";

        // 字符串拼接
        postString = (char *)malloc(strlen(key) + strlen(secret) + 2048);
        sprintf(postString, "img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s", "", "", key, secret, typeId, format);

        curl = curl_easy_init();
        if (curl)
        {
                // 指定cookie缓存文件
                if (curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt") != CURLE_OK)
                {
                        fprintf(stderr, "Failed to set cookie file\n");
                        // 处理错误
                        return false; // 在设置失败时,直接返回
                }
                // 指定post传输内容,get请求将URL和postString一次性发送
                curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postString);
                // 指定url
                curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do");
                // 回调函数读取返回值
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, readData);

                // 执行请求
                res = curl_easy_perform(curl);
                if (res != CURLE_OK)
                {
                        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
                        // 处理错误
                        return false;
                }

                // 清理资源
                curl_easy_cleanup(curl);
        }
        // 释放动态分配的内存
        free(postString);

        return true;
}

int main(void)
{
        postUrl();

        return 0;
}

编译

gcc ocr.c -I /home/orangepi/curl-7.71.1/_install/include/ -L /home/orangepi/curl-7.71.1/_install/lib/ -lcurl

运行

成功运行后,已经可以看到已经收到了翔云后台的反馈:
在这里插入图片描述

四、Base64编码

Base64 是一种二进制到文本编码方式,通过将二进制数据编码为 ASCII 字符集中的字符,使得数据能够以文本形式传输,而不会被改变。Base64 编码通常用于在文本协议中传输二进制数据,例如电子邮件的附件、图片的网址传输等。

Base64 编码的基本原理是将每三个字节的数据(24 位)转换为四个 Base64 字符。这样,原始数据的大小会增加约 1/3。

Base64 字符集通常包含 64 个字符,包括:

  1. 26 个大写字母: A-Z
  2. 26 个小写字母: a-z
  3. 10 个数字: 0-9
  4. 两个额外字符: + 和 /

Base64 不使用常见的字符,因此它是一种安全的编码方式,适用于在文本协议中传输二进制数据。

编码过程如下:

  1. 将数据按每三个字节(24 位)进行分组。
  2. 将每组数据划分为四个 6 位的片段。
  3. 将这些 6 位的片段转换为 Base64 字符。

Base64 解码则是编码的逆过程,将 Base64 字符转换回原始的二进制数据。在编码和解码过程中,Base64 字符集提供了一种标准的、文本友好的表示形式,使得数据在各种环境中都能够被正确处理。

示例:

原始数据:   Hello, World!
Base64 编码:SGVsbG8sIFdvcmxkIQ==

在编程中,大多数编程语言都提供了 Base64 编码和解码的库或函数,方便开发者在应用中使用。

五、RGB颜色模型(用于表示图像中的颜色信息)

RGB(Red, Green, Blue)是一种颜色模型,用于表示图像中的颜色信息。在 RGB 模型中,每个像素的颜色由红色(R)、绿色(G)、蓝色(B)三个分量的亮度组合而成。每个分量的取值通常在 0 到 255 之间,其中 0 表示最小亮度,255 表示最大亮度。

RGB 数据表示一个图像的颜色信息,通常以矩阵的形式存储。每个像素由一个或多个字节组成,其中每个字节对应一个颜色分量。在常见的图像文件格式中,像素的存储顺序通常是连续的,按行或按列排列。

以下是一个简单的示例,展示了一个 3x3 的图像的 RGB 数据:

| R0 G0 B0 | R1 G1 B1 | R2 G2 B2 |
| R3 G3 B3 | R4 G4 B4 | R5 G5 B5 |
| R6 G6 B6 | R7 G7 B7 | R8 G8 B8 |

这里,每组 R G B 表示一个像素的红、绿、蓝三个分量的值。在实际应用中,图像的大小可能是数百乃至数千像素,而 RGB 数据的表示会更加庞大。

在编程中,处理 RGB 数据通常需要使用专门的图像处理库,例如 OpenCV(Open Source Computer Vision Library)等。这些库提供了丰富的函数和工具,方便开发者对图像进行处理、分析和操作。
BMP(Bitmap)是一种位图图像文件格式,它是一种无损压缩的图像格式,通常以.bmp为文件扩展名。BMP 文件格式最初由Microsoft开发,用于Windows平台。

六、BMP 图像以像素矩阵的形式存储

BMP 图像以像素矩阵的形式存储,每个像素可以用来表示图像中的一个点,而每个点的颜色信息则通过RGB(Red, Green, Blue)三个分量来表示。BMP 文件格式支持不同的颜色深度,包括1位、4位、8位、16位、24位和32位等多种格式。

BMP 文件的结构包括文件头和图像数据两个主要部分:

  1. 文件头(Bitmap File Header): 包含了文件的一些基本信息,比如文件类型、文件大小、图像的偏移等。

  2. 信息头(Bitmap Information Header): 包含了关于图像的详细信息,如图像的宽度、高度、颜色平面数、每像素比特数等。

  3. 颜色表(Color Table): 针对使用调色板的图像,包含了调色板中的颜色信息。

  4. 图像数据: 包含了图像的实际像素数据。

BMP 文件通常比较简单,易于理解和解析。然而,由于它不使用压缩算法,因此可能占用较大的存储空间,尤其是对于彩色图像。在实际应用中,更常见的图像格式如JPEG、PNG等采用了更高效的压缩算法。

常见的图像格式

有许多不同的图像格式,每种格式都有其特定的用途和优势。以下是一些常见的图像格式:

  1. JPEG(Joint Photographic Experts Group): 一种有损压缩格式,适用于照片和真彩图像。它通过牺牲一些图像细节来实现更小的文件大小。

  2. PNG(Portable Network Graphics): 一种无损压缩格式,适用于图标、图形和带有透明背景的图像。PNG支持多种颜色深度和透明度。

  3. GIF(Graphics Interchange Format): 一种支持动画和透明度的格式。GIF适用于简单的图形,但由于其有限的颜色深度,不适用于照片。

  4. BMP(Bitmap): 一种无损格式,适用于简单的图像。BMP文件通常较大,因为它们未经压缩。

  5. TIFF(Tagged Image File Format): 一种灵活的格式,适用于存储高质量的图像和照片。TIFF支持无损压缩和多页文档。

  6. WEBP: 由Google开发的一种图像格式,支持有损和无损压缩,同时具有较小的文件大小。

  7. SVG(Scalable Vector Graphics): 一种矢量图形格式,适用于图标和图形。SVG图像可缩放而不失真。

  8. RAW: 一种未经处理的图像格式,通常由数码相机生成。RAW格式保留了更多的图像信息,但文件较大。

  9. ICO(Icon): 用于存储图标的格式,通常用于Windows应用程序。

这只是一小部分常见的图像格式,实际上还有许多其他专用格式和变种,每种都适用于不同的用途。选择图像格式时,通常要考虑图像的内容、用途、质量和文件大小。

七、Base64数据格式转换

Base64是一种将二进制数据编码成ASCII字符串的方法,通常用于在文本协议中传输二进制数据。你可以使用Base64编码工具对图像进行编码,以下是一个示例:

base64 test.jpg > test_base64.txt

这将把 test.jpg 图像文件编码为Base64,并将结果保存到 test_base64.txt 文件中。

如果你想要将Base64字符串解码回二进制数据,可以使用以下命令:

base64 -d test_base64.txt > test_decoded.jpg

这将从 test_base64.txt 文件中读取Base64字符串并将其解码为 test_decoded.jpg 图像文件。

请注意,Base64编码会增加数据的大小,因为它将二进制数据转换为文本形式。在网络传输中使用它可以确保数据以文本的形式传递,但需要考虑到编码和解码的性能开销。

常用的Base64加密解密工具网站

一些常用的Base64加密解密工具网站包括:

  1. Base64 编码解码 - 在线工具
  2. Online Base64 编码解码
  3. Base64 编码/解码工具

请记住在使用在线工具时要谨慎,特别是在处理敏感数据时,因为在线服务可能会记录你的数据。如果你处理敏感信息,请尽量使用本地工具。

八、加入图片base64编码

Base64是网络上最常见的用于传输8Bit字节码的编码方式之一,可用于在HTTP环境下传递较长的标识信息。
在这里插入图片描述

在Linux下生成图片的base64编码

base64 test.jpg

在这里插入图片描述

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>

char* getBase64FromFile(const char* filePath)
{
    char cmd[256] = {'\0'};
    char* base64Buf = NULL;

    // 使用安全的方式构建命令
    snprintf(cmd, sizeof(cmd), "base64 %s | tr -d '\n' > tmpFile", filePath);//图片的base64流导入到文件中

    if (system(cmd) == -1) {
        perror("Error executing system command");
        return NULL;
    }

    int fd = open("./tmpFile", O_RDWR);
    if (fd == -1) {
        perror("Error opening file");
        return NULL;
    }

    // 计算文件大小
    int fileLen = lseek(fd, 0, SEEK_END);
    lseek(fd, 0, SEEK_SET);

    // 动态分配内存
    base64Buf = (char*)malloc(fileLen + 1);
    if (base64Buf == NULL) {
        perror("Error allocating memory");
        close(fd);
        return NULL;
    }

    memset(base64Buf, '\0', fileLen + 1);

    // 读取文件内容到字符串(base64流)
    if (read(fd, base64Buf, fileLen) == -1) {
        perror("Error reading file");
        free(base64Buf);
        close(fd);
        return NULL;
    }

    close(fd);

    // 删除临时文件
    if (remove("tmpFile") == -1) {
        perror("Error deleting temporary file");
    }

    return base64Buf;
}

int main() {
    const char* filePath = "your_file_path_here";
    char* base64String = getBase64FromFile(filePath);

    if (base64String != NULL) {
        printf("Base64 String:\n%s\n", base64String);

        // 释放动态分配的内存
        free(base64String);
    }

    return 0;
}

九、人脸识别完整代码及功能点实现现象

ocr.c

#include <stdio.h>
#include <curl/curl.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

// 定义bool类型和常量
typedef unsigned int bool; // 数据类型别名用typedef
#define true 1
#define false 0

char ocrReturnBuf[1024] = {'\0'}; // 全局变量,用来接收从OCR后台返回的数据

// 回调函数,读取从OCR后台返回的数据(把从后台的数据拷贝给ocrReturnBuf)
size_t readData(void *ptr, size_t size, size_t nmemb, void *stream)
{
        size_t totalSize = size * nmemb;

        // 为了避免溢出,计算实际拷贝的长度
        size_t copySize = (totalSize < (sizeof(ocrReturnBuf) - 1)) ? totalSize : (sizeof(ocrReturnBuf) - 1);

        // 拷贝数据到 ocrRetBuf 中
        memcpy(ocrReturnBuf, ptr, copySize);

        // 手动添加字符串终结符
        ocrReturnBuf[copySize] = '\0';

        return totalSize;
}

char *getBase64FromFile(const char *filePath)
{
        char cmd[256] = {'\0'};
        char *base64Buf = NULL;

        // 使用安全的方式构建命令
        snprintf(cmd, sizeof(cmd), "base64 %s | tr -d '\n' > tmpFile", filePath);

        if (system(cmd) == -1) {
                perror("Error executing system command");
                return NULL;
        }

        int fd = open("./tmpFile", O_RDWR);
        if (fd == -1) {
                perror("Error opening file");
                return NULL;
        }

        // 计算文件大小
        int fileLen = lseek(fd, 0, SEEK_END);
        lseek(fd, 0, SEEK_SET);

        // 动态分配内存
        base64Buf = (char *)malloc(fileLen + 1);
        if (base64Buf == NULL) {
                perror("Error allocating memory");
                close(fd);
                return NULL;
        }

        memset(base64Buf, '\0', fileLen + 1);

        // 读取文件内容到字符串
        if (read(fd, base64Buf, fileLen) == -1) {
                perror("Error reading file");
                free(base64Buf);
                close(fd);
                return NULL;
        }

        close(fd);

        // 删除临时文件
        if (remove("tmpFile") == -1) {
                perror("Error deleting temporary file");
        }

        return base64Buf;
}

// 根据文档,接口调用方法为post请求
bool postUrl()
{
        CURL *curl;
        CURLcode res;

        // 根据翔云平台的接口要求  分开定义,然后字符串拼接
        char *img1 = getBase64FromFile("/home/orangepi/smart_home/test/test1_JPEG.webp"); // 图片base64流
        char *img2 = getBase64FromFile("/home/orangepi/smart_home/test/test2_JPEG.webp");
        char *key = "JFD5c1iBh9LVqPkkZMxxxx";
        char *secret = "76f444813fc945bd9543e4d7e086xxxx";
        int typeId = 21;
        char *format = "xml";

        int len = strlen(key) + strlen(secret) + strlen(img1) + strlen(img2) + 128; // 分配空间不够会>导致栈溢出
        char* postString = (char*)malloc(len);
        memset(postString, '\0', len);//因为postString是一个指针,不能用sizeof来计算其指向的大小

        // 字符串拼接
        sprintf(postString, "img1=%s&img2=%s&key=%s&secret=%s&typeId=%d&format=%s", img1, img2, key, secret, typeId, format);

        curl = curl_easy_init();
        if (curl)
        {
                // 指定cookie缓存文件
                // if (curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "/tmp/cookie.txt") != CURLE_OK)
                // {
                //         fprintf(stderr, "Failed to set cookie file\n");
                //         return false; // 在设置失败时,直接返回
                // }
                // 指定post传输内容,get请求将URL和postString一次性发送
                curl_easy_setopt(curl, CURLOPT_POSTFIELDS, postString);
                // 指定url
                curl_easy_setopt(curl, CURLOPT_URL, "https://netocr.com/api/faceliu.do");
                // 回调函数读取返回值
                curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, readData);

                // 执行请求
                res = curl_easy_perform(curl);
                if (res != CURLE_OK) {
                        fprintf(stderr, "curl_easy_perform() failed: %s\n", curl_easy_strerror(res));
                        // 处理错误
                        return false;
                }

                //字符串检索 判断翔云后台返回的一大堆字符串中有没有“否”
                if (strstr(ocrReturnBuf,"否") != NULL) {    
                        printf("不是同一个人\n");
                }
                else{
                        printf("是同一个人\n");
                }

                // 清理资源
                curl_easy_cleanup(curl);
        }
        // 释放动态分配的内存
        free(img1);
        free(img2);
        free(postString);

        return true;
}

int main(void)
{
        postUrl();

        return 0;
}

编译

gcc ocr.c -I /home/orangepi/curl-7.71.1/_install/include/ -L /home/orangepi/curl-7.71.1/_install/lib/ -lcurl

运行

在这里插入图片描述
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/233024.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

距离度量(各距离含义)

欧氏距离 在n维空间中两点的真实距离&#xff0c;向量的自然长度 由于欧几里得几何学的关系称为欧氏距离 二维空间两点计算公式&#xff1a; d ( x 1 − x 2 ) 2 ( y 1 − y 2 ) 2 d \sqrt{(x_1 - x_2)^2 (y_1 - y_2)^2} d(x1​−x2​)2(y1​−y2​)2 ​ 三维空间两点计算…

fl studio2024试用版本如何汉化中文?

fl studio2024全称Fruity Loops Studio2024&#xff0c;这款软件也被人们亲切的称之为水果&#xff0c;它是一款功能强大的音乐创作编辑软件&#xff0c;拥有全功能的录音室&#xff0c;大混音盘以及先进的音乐制作工具&#xff0c;用户通过使用该软件&#xff0c;就可以轻松制…

springboot mybatis手动事务

创建springboot项目 搭建最简单的SpringBoot项目-CSDN博客 引入mybatis和数据库依赖 <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><…

树莓派CSI摄像头在新系统(23年12月)中的不用设置了,没有开关,也没有raspistill

网上都是老信息&#xff0c;用的raspistill命令&#xff0c;至少新系统没有这个东西了&#xff0c;也不会在sudo raspi-config里面也没有摄像头的开关了。 ls /dev/video* 能看到摄像头video0&#xff0c;但是vcgencmd get_camera supported0&#xff0c; detected0&#xff0…

排序算法之四:直接选择排序

1.基本思想 每一次从待排序的数据元素中选出最小&#xff08;或最大&#xff09;的一个元素&#xff0c;存放在序列的起始位置&#xff0c;直到全部待排序的数据元素排完 。 2.直接选择排序 在元素集合array[i]--array[n-1]中选择关键码最大(小)的数据元素 若它不是这组元素中的…

数字系统设计(EDA)实验报告【出租车计价器】

一、问题描述 题目九&#xff1a;出租车计价器设计&#xff08;平台实现&#xff09;★★ 完成简易出租车计价器设计&#xff0c;选做停车等待计价功能。 1、基本功能&#xff1a; &#xff08;1&#xff09;起步8元/3km&#xff0c;此后2元/km&#xff1b; &#xff08;2…

【工厂方法】设计模式项目实践

前言 以采集数据处理逻辑为例&#xff0c;数据采集分为不同种类如&#xff1a;MQTT、MODBUS、HTTP等&#xff0c;不同的采集数据有不同的解析处理逻辑。但总体解析处理步骤是固定的。可以使用工厂方法设计模式简化代码&#xff0c;让代码变得更加优雅。 代码实践 抽象类 总体…

蒙特霍尔问题(选择三扇门后的车与羊)及其贝叶斯定理数学解释

1. 蒙特霍尔问题 有一个美国电视游戏节目叫做“Let’s Make a Deal”&#xff0c;游戏中参赛者将面对3扇关闭的门&#xff0c;其中一扇门背后有一辆汽车&#xff0c;另外两扇门后是山羊&#xff0c;参赛者如果能猜中哪一扇门后是汽车&#xff0c;就可以得到它。 通常&#xf…

工业4.0分类:数字化转型的多维度

引言 工业4.0代表着制造业的数字化革命&#xff0c;它将制造过程带入了数字时代。然而&#xff0c;工业4.0并不是一个单一的概念&#xff0c;而是一个多维度的范畴&#xff0c;包括不同的技术、应用领域、企业规模和实施方式。但在这一多维度的概念中&#xff0c;低代码技术正…

shell基本知识

Linux 系统中 shell 的基本知识 1 什么是 shell Shell 是一种命令行解释器&#xff0c;它为用户提供了一个向 Linux 内核发送请求以便运行程序的界面系统级程序。用户可以用 shell 来启动、挂起、停止甚至是编写一些程序。 2 Linux 启动过程 Linux 系统的启动过程可以概括为…

[强网拟态决赛 2023] Crypto

文章目录 Bad_rsaClasslcal Bad_rsa 题目描述&#xff1a; from Crypto.Util.number import *f open(flag.txt,rb) m bytes_to_long(f.readline().strip())p getPrime(512) q getPrime(512) e getPrime(8) n p*q phi (p-1)*(q-1) d inverse(e,phi) leak d & ((1…

L1-032:Left-pad

题目描述 根据新浪微博上的消息&#xff0c;有一位开发者不满NPM&#xff08;Node Package Manager&#xff09;的做法&#xff0c;收回了自己的开源代码&#xff0c;其中包括一个叫left-pad的模块&#xff0c;就是这个模块把javascript里面的React/Babel干瘫痪了。这是个什么样…

【11】Qt Designer

目录 VSCode添加外部工具 QtDesigner PyUIC PyRCC 加载UI文件模板代码 QMainWindow QWidget 常用知识点 1. 修改标题图标 2. 图片资源管理 3. 图片按钮 4. 加载对话框 5. 动态加载Widget 6. 修改主题 其他注意事项 事件被多次触发 PyQt5提供了一个可视化图形工…

【springboot设计源码】庆阳非物质文化遗产展示平台课题背景、目的、意义、研究方法

该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程等学习内容。 目录 一、项目介绍&#xff1a; 二、文档学习资料&#xff1a; 三、模块截图&#xff1a; 四、开发技术与运行环境&#xff1a; 五、代码展示&#xff1a; 六、数据库表截图&#xff1…

正在快速兴起的云数据架构

云数据架构的日益流行表明了一个主题&#xff1a;在未来几年&#xff0c;越来越多的企业将把他们的数据中心业务完全迁移到云平台上&#xff0c;因为内部部署数据中心设施具有一些固有的优势。数字时代的企业生存已经成为向云迁移的代名词。 云数据架构的日益流行表明了一个主…

sqlite3.44.2的编译

文章目录 sqlite3.44.2的编译概述笔记解决shell.c编译报错的方法整理 - 正常可用的编译脚本过程剩下的事情验证编译出的输出是否可以给工程正常使用?END sqlite3.44.2的编译 概述 想从源码编译一份Sqlite3.44.2出来. 编译sqlite3.44.2前置需要的TCL环境已经编译出来到了, 做…

排序:挖坑快排前后指针快排

目录 挖坑快排&#xff1a; 代码实现&#xff1a; 代码分析&#xff1a; 前后指针快排&#xff1a; ​编辑动画分析&#xff1a; 代码分析&#xff1a; 代码演示&#xff1a; 快排的优化&#xff1a;三数取一 挖坑快排&#xff1a; 挖坑法&#xff0c;顾名思义&am…

球上进攻^^

欢迎来到程序小院 球上进攻 玩法&#xff1a;点击鼠标走动躲避滚动的球球&#xff0c;球球碰到即为游戏结束&#xff0c;看看你能坚持多久&#xff0c;快去玩吧^^。开始游戏https://www.ormcc.com/play/gameStart/214 html <div id"game" class"game" …

Vue3组合式API详解

目录 一、setup详解 二、ref详解 三、computed详解 四、watch详解 &#xff08;1&#xff09;监听单个数据的变化 &#xff08;2&#xff09;监听多个数据的变化 &#xff08;3&#xff09;immediate &#xff08;4&#xff09;deep &#xff08;5&#xff09;精确监听…

排序:非递归的快排

目录 非递归的快排&#xff1a; 代码分析&#xff1a; 代码演示&#xff1a; 非递归的快排&#xff1a; 众所周知&#xff0c;递归变成非递归&#xff0c;而如果还想具有递归的功能&#xff0c;那么递归的那部分则需要变成循环来实现。 而再我们的排序中&#xff0c;我们可…