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

【Docker】镜像安全扫描工具clair与clairctl

【Docker】镜像安全扫描工具clair与clairctl镜像扫描结构图方式2的具体操作步骤clair是什么clair是一个开源项目用于静态分析appc和docker容器中的漏洞。 漏洞元数据从一组已知的源连续导入并与容器映像的索引内容相关联以生成威胁容器的漏洞列表。clair版本选择clair选择2.0.1版本clair安装过程docker方式1.clair将漏洞元数据存储在Postgres中先拉取postgres:9.6docker pull postgres:9.62.使用官方镜像clair:v2.0.1并进行拉取docker pull quay.io/coreos/clair:v2.0.13.创建clair的配置文件存放的文件夹mkdir /root/clair/_config4.下载clair的配置文件主要是对数据库连接方式的配置curl -L https://raw.githubusercontent.com/coreos/clair/v2.0.1/config.example.yaml -o /root/clair/_config/config.yaml5.运行postgres容器docker run -d -e POSTGRES/_PASSWORD“” -p 5432:5432 postgres:9.66.运行clair容器docker run --nethost -d -p 6060-6061:6060-6061 -v /root/clair/_config:/config quay.io/coreos/clair:v2.0.1 -config/config/config.yaml注此时clair容器不断从各个数据站点下载漏洞数据源并存放至数据库中非常耗时存在大量数据站点无法请求的情况。若此时漏洞元数据可以下载可继续以下步骤7.安装辅助工具clairctlclairctl一个轻量级命令行工具用于在本地使用clair并生成HTML报告。Clairctl需要go语言支持7.1 下载go支持包https://storage.googleapis.com/golang/go1.8.3.linux-amd64.tar.gz7.2 解压tar -zxvf go1.8.3.linux-amd64.tar.gz /usr/local/go7.3 设置环境变量export PATH$PATH:/usr/local/go/binexport GOROOT/usr/local/go7.4 确认go版本go version7.5 安装clairctlcurl -L https://raw.githubusercontent.com/jgsqware/clairctl/master/install.sh | sh7.6 确认clairctl版本clairctl version7.7 检查clairctl与Clair的连接clairctl health如果显示✔则说明clairctl和clair能够进行正常连接。8.上传镜像至clairclairctl push -l nginx9.分析本地镜像clairctl analyze -l nginx在分析时生成详细的分析文档clairctl analyze -l --log-level debug nginx10.生成结果如果希望堪当更加详细的信息可以使用report命令clairctl report -l nginx11.查看clair分析的具体步骤clairctl analyze -l --log-level debug nginx备注192.168.2.186 root Beyond#11 clair用的是最新版也可以使用v2.0.1版本需要等待2、3个小时让漏洞元下载下来目前这种方式可以成功push与analyze nginx但查不出任何漏洞要么nginx本身就没有漏洞要么就是没有进行比对push其他镜像时出现了问题该问题暂不知道解决方式。docker-compose方式1.安装docker-composecurl -L https://github.com/docker/compose/releases/download/1.24.1/docker-compose-uname -s-uname -m-o /usr/local/bin/docker-composechmod x /usr/local/bin/docker-compose检查版本docker-compose --version2.将以下代码保存在/root目录下的docker-compose.yml中version: 2.1 services: postgres: image: postgres:9.6 restart: unless-stopped volumes: - ./data/postgres/data:/var/lib/postgresql/data:rw environment: - POSTGRES_PASSWORDpassword - POSTGRES_USERclair - POSTGRES_DBclair clair: image: quay.io/coreos/clair:v2.0.1 restart: unless-stopped volumes: - ./data/clair/config/:/config/:ro - ./data/clair/tmp/:/tmp/:rw depends_on: postgres: condition: service_started command: [--log-leveldebug, --config, /config/config.yml] clairctl: image: jgsqware/clairctl:latest restart: unless-stopped environment: - DOCKER_API_VERSION1.24 volumes: - ./data/clairctl/reports/:/reports/:rw - /var/run/docker.sock:/var/run/docker.sock:ro depends_on: clair: condition: service_started3.将以下配置代码保存在/root/data/clair/config目录中的config.yml中clair: database: type: pgsql options: source: postgresql://clair:passwordpostgres:5432/clair?sslmodedisable cachesize: 16384 api: port: 6060 healthport: 6061 timeout: 900s updater: interval: 2h notifier: attempts: 3 renotifyinterval: 2h4.在docker-compose.yml的路径下构建镜像并启动容器docker-compose up -d5.因为clairctl的官方镜像中的用户限定为clairctl因此更改权限chmod 777 /var/run/docker.sock6.确认docker-compose启动的容器信息docker-compose ps7.确认clairctl与clair的连接状况docker-compose exec clairctl clairctl health8.将本地镜像push到clairdocker-compose exec clairctl clairctl push -l nginx9.分析镜像docker-compose exec clairctl clairctl analyze -l nginx10.生成HTML报告docker-compose exec clairctl clairctl report -l nginx调用clair的api方式先看clair v2.0.1的api文档示例请求POST http://localhost:6060/v1/layers HTTP/1.1{ Layer: { Name: 523ef1d23f222195488575f52a39c729c76a8c5630c9a194139cb246fb212da6, Path: https://mystorage.com/layers/523ef1d23f222195488575f52a39c729c76a8c5630c9a194139cb246fb212da6/layer.tar, Headers: { Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiY WRtaW4iOnRydWV9.EkN-DOsnsuRjRO6BxXemmJDm3HbxrbRzXglbN2S4sOkopdU4IsDxTI8jO19W_A4K8ZPJijNLis4EZsHeY559a4DFOd50_OqgHGu ERTqYZyuhtF39yxJPAjUESwxk2J5k_4zM3O-vtd1Ghyo4IbqKKSy6J9mTniYJPenn5-HIirE }, ParentName: 140f9bdfeb9784cf8730e9dab5dd12fbd704151cf555ac8cae650451794e5ac2, Format: Docker } }该步操作是将指定镜像的每一层按照顺序push到clair中。官网说明为了分析容器图像必须按照正确的顺序push某个镜像的所有层。例如要分析由三层A- B- C组成的图像其中A是基础层必须对此路径进行三次API调用从A到C.此外在分析B时必须将A设置为父级然后在分析C时必须将B定义为父级。Name为层id,或为一个不与其他图层id重复的字符串Path位图层的下载地址Authorization字段是一个可选值可选其内容将在通过HTTP请求图层时填充Authorization HTTP Header。ParentName为父级idFormat固定为Docker因此目前我们的思路为打包测试用的image再将解压后的文件复制到tomcat的ROOT目录中在post的过程中注意层级的父子关系。1.将某个镜像打包docker save -o /root/data/nginx.tar nginx:latest2.解压该镜像tar -xvf nginx.tar3.查看镜像的层级关系vi manifest.json输出[{ Config: e445ab08b2be8b178655b714f89e5db9504f67defd5c7408a00bade679a50d44.json, RepoTags: [nginx:latest], Layers: [ 08029cfa8b0dcfe678e23255feef9c9f1a08c39ebf6faffc4e5ee8b6ec63ff1f/layer.tar, 656e37151781143bab1be21edfbe2de2251ffe28e8d2004e83cd79a7a76d0b81/layer.tar, 22e7e6fdc1e671b8f4d55efa2e707cf4ac35e34d757efc2b43c219be7a800ae4/layer.tar ] }]由此可知08029为最底层656e为中间层22e7为最上层。4.复制文件到tomcat的ROOT目录中cp -r /root/data//* /usr/local/apache-tomcat-8.5.42/webapps/ROOT5.发起请求5.1 push最底层请求示例post http://192.168.2.186:6060/v1/layers { Layer: { Name: 08029cfa8b0dcfe678e23255feef9c9f1a08c39ebf6faffc4e5ee8b6ec63ff1f, Path: http://localhost:8080/08029cfa8b0dcfe678e23255feef9c9f1a08c39ebf6faffc4e5ee8b6ec63ff1f/layer.tar, Format: Docker } }5.2 push中间层请求示例post http://192.168.2.186:6060/v1/layers { Layer: { Name: 656e37151781143bab1be21edfbe2de2251ffe28e8d2004e83cd79a7a76d0b81, Path: http://localhost:8080/656e37151781143bab1be21edfbe2de2251ffe28e8d2004e83cd79a7a76d0b81/layer.tar, ParentName: 08029cfa8b0dcfe678e23255feef9c9f1a08c39ebf6faffc4e5ee8b6ec63ff1f, Format: Docker } }5.3 push最上层请求示例post http://192.168.2.186:6060/v1/layers { Layer: { Name: 22e7e6fdc1e671b8f4d55efa2e707cf4ac35e34d757efc2b43c219be7a800ae4, Path: http://localhost:8080/22e7e6fdc1e671b8f4d55efa2e707cf4ac35e34d757efc2b43c219be7a800ae4/layer.tar, ParentName: 656e37151781143bab1be21edfbe2de2251ffe28e8d2004e83cd79a7a76d0b81, Format: Docker } }6.获取镜像漏洞请求示例get http://192.168.2.186:6060/v1/layers/22e7e6fdc1e671b8f4d55efa2e707cf4ac35e34d757efc2b43c219be7a800ae4?featuresvulnerabilities响应示例{ Layer: { Name: 22e7e6fdc1e671b8f4d55efa2e707cf4ac35e34d757efc2b43c219be7a800ae4, NamespaceName: debian:10, ParentName: 656e37151781143bab1be21edfbe2de2251ffe28e8d2004e83cd79a7a76d0b81, IndexedByVersion: 3, Features: [ { Name: libgd2, NamespaceName: debian:10, VersionFormat: dpkg, Version: 2.2.5-5.2, AddedBy: 656e37151781143bab1be21edfbe2de2251ffe28e8d2004e83cd79a7a76d0b81 }, { Name: openssl, NamespaceName: debian:10, VersionFormat: dpkg, Version: 1.1.1c-1, AddedBy: 656e37151781143bab1be21edfbe2de2251ffe28e8d2004e83cd79a7a76d0b81 }, { Name: util-linux, NamespaceName: debian:10, VersionFormat: dpkg, Version: 2.33.1-0.1, AddedBy: 08029cfa8b0dcfe678e23255feef9c9f1a08c39ebf6faffc4e5ee8b6ec63ff1f }, ........... ] } }备注这种方式和第一种方式在分析nginx时得到了相同的分析结果未发现任何漏洞2019/0905再次调研结果无任何本质性改变此外clairctl在两年前就已经停更存在的问题很多安装中出现的问题1.clair官方镜像下载速度很慢配置阿里云镜像加速依然无效多次出现下载失败的情形。2.clairctl官方github提供的安装命令中出现的部分链接已经失效。3.clair更新漏洞元数据频繁出现超时、文件解析等错误。在多次更换版本的情况下尝试了2.0.1与最新版v2.0.9依然未解决。在漏洞元数据未更新完全的情况下使用分析命令后得不到正确的结果。总结一、之前的扫描镜像原理之前的镜像扫描采用的是clair的1.0版本首先前端发起扫描请求后端接收到请求后再调用abcsys服务abcsys调用clairctl,clairctl在内部调用clair的api可能由于clair的版本太低出现了很多镜像不支持的问题。二、使用中出现的问题(1)漏洞元下载缓慢经查阅信息漏洞元数据需要3个小时左右才可以下载完毕。(2)扫描任何镜像都查不出漏洞经过排查发现特征-漏洞关系表下载不下来导致clair仅能分析出特征而不能扫描出漏洞目前该问题无法解决。下载不下来的问题可能由于该地址已经失效或者需要代理才可以访问。三、两个可选的clair扫描策略(1)继续使用clairctlclair的扫描方式但clairctl停更已久可能会出现意想不到的问题。(2)直接使用clair api的方式只不过这个需要分层提交。这样避免使用clairctl在漏洞元数据填充完毕后调用方将获得扫描的json字符串解析简单方便。但这样的缺点是需要分层提交。参考文档1.clair官网2.clair官方Github3.clair官方api4.clairctl官方github5.安全防护工具之Clair6.安全工具无疾而终的clairctl安装出现问题的解决记录[1]open file:permission denied尽管给文件设置777权限后依然被拒绝解决方案https://github.com/coreos/clair/issues/707执行命令setenforce 0 注意这只是临时解决方式一旦机器重启则依然出现权限拒绝的问题因此需要永久性解决永久解决方案https://www.cnblogs.com/ftl1012/p/selinux.html该方案未尝试[2]postgres数据库出现大量的同步错误解决方案可以下载210上的postgres中的public库目前该库是harbor集成clair所依赖的数据库该数据库中存储的漏洞比较全且表结构与v2.0.1的clair所依赖的数据库一致可以直接导入到postgres中。但依然会在导入的过程中出现问题即使删除postgres中的库直接复制库也不行。在复制库的过程中会出现主键丢失与数据丢失的问题造成的结果就是clair分析出的漏洞不全。该问题暂时未解决估摸着是外键依赖的问题。[3]clairctl无法向clair push镜像clairctl虽然能与clair正常连接即clairctl能对clair进行健康检查。但clairctl无法向clair push镜像会收到clair 400的错误。目前该问题未解决。可能的原因clairctl的版本和clair的版本不对应造成clairctl的请求和clair的api对不上的问题。最终可用版数据库方面的考虑为了避免clair依赖的postgres数据同步失败或不完整的情况以及为了好harbor的扫描结果一致因此打算直接使用harbor的扫描漏洞库。因此需要需要添加配置文件config.yml在/root/data/clair/config下添加config.ymldatabase: type: pgsql options: source: postgresql://postgres:password192.168.2.194:5432/postgres?sslmodedisable cachesize: 16384 api: port: 6060 healthport: 6061 timeout: 900s updater: interval: 2h notifier: attempts: 3 renotifyinterval: 2h启动clair运行命令docker run --nethost -d -p 6060-6061:6060-6061 -v /root/data/clair/config:/config quay.io/coreos/clair:v2.0.1 -config/config/config.yml请求clair的api(1)将镜像打包并解压至tomcat的ROOT目录中这一步主要是提供一个模拟的服务器用于提供待扫描镜像的每一层的下载地址。(2)获取ROOT目录中的manifest.json此文件是描述该镜像的层序结构。{ Config: 158ad321fec9a1621f3251d68f91d53f1003c93cca29ded31d00bd1ade2c3a47.json, RepoTags: [ 192.168.2.194/public/fabric-node:0.0.6rc17 ], Layers: [ c5da0099e17668eceecd5f30e5b2012089d9def80a64be8a9e6adc85197528a7/layer.tar, dc875156727c2cd7c2f8c85aaa2fe5f33a4ff699edd52ab2b021f7abc74a16c6/layer.tar, 48a07fbdca8996ebce7ff7ad95c793a57b1676e2b05ec32bb2bfde32025e90ed/layer.tar, bd85a4f03f646be6fc9393230f98053bc44de3346ffa96da51f1307eb1f43ee4/layer.tar, cc4a551d9f992fc502d601340febca9ba5eecbbf006e3cfb38269fb4f29960cb/layer.tar, c90086e0cafb06746235f5139b9e5dbfdfe29ad4478eed876be2766cbc097222/layer.tar, 3997751112581455a0b622c5b6ce74cffabd0be2507b345450caa505a358f7f2/layer.tar ] }(3)循环layers,依次请求clair的api以第二层为例POST http://192.168.2.186:6060/v1/layers { Layer: { Name: dc875156727c2cd7c2f8c85aaa2fe5f33a4ff699edd52ab2b021f7abc74a16c6, Path: http://localhost:8080/dc875156727c2cd7c2f8c85aaa2fe5f33a4ff699edd52ab2b021f7abc74a16c6/layer.tar, ParentName: c5da0099e17668eceecd5f30e5b2012089d9def80a64be8a9e6adc85197528a7, Format: Docker } }其中Name为镜像该层的名称Path为该层的下载地址Parent为该层的父层名称当该层已经是第一层是则不传该参数Format格式固定为Docker获取分析结果其中镜像名称为最后一层的名称数据库会按照当初存入的层级关系一直找到该层链接的所有层并将所有层的特征-漏洞二元组返回。GET http://192.168.2.186:6060/v1/layers/3997751112581455a0b622c5b6ce74cffabd0be2507b345450caa505a358f7f2?featuresvulnerabilities返回结果示例{ Layer:{ Name:3997751112581455a0b622c5b6ce74cffabd0be2507b345450caa505a358f7f2, NamespaceName:centos:7, ParentName:c90086e0cafb06746235f5139b9e5dbfdfe29ad4478eed876be2766cbc097222, IndexedByVersion:3, Features:Array[145] } }《网络安全从零到精通全套学习大礼包》96节从入门到精通的全套视频教程免费领取如果你也想通过学网络安全技术去帮助就业和转行我可以把我自己亲自录制的96节 从零基础到精通的视频教程以及配套学习资料无偿分享给你。网络安全学习路线图想要学习 网络安全作为新手一定要先按照路线图学习方向不对努力白费。对于从来没有接触过网络安全的同学我帮大家准备了从零基础到精通学习成长路线图以及学习规划。可以说是最科学最系统的学习路线大家跟着这个路线图学习准没错。配套实战项目/源码所有视频教程所涉及的实战项目和项目源码学习电子书籍学习网络安全必看的书籍和文章的PDF市面上网络安全书籍确实太多了这些是我精选出来的面试真题/经验以上资料如何领取g.cn/direct/4fd5acecbff8471098d6b027b62f45d5.png#pic_center)学习电子书籍学习网络安全必看的书籍和文章的PDF市面上网络安全书籍确实太多了这些是我精选出来的面试真题/经验以上资料如何领取文章来自网上侵权请联系博主

相关文章:

【Docker】镜像安全扫描工具clair与clairctl

【Docker】镜像安全扫描工具clair与clairctl 镜像扫描结构图 方式2的具体操作步骤 clair是什么? clair是一个开源项目,用于静态分析appc和docker容器中的漏洞。 漏洞元数据从一组已知的源连续导入,并与容器映像的索引内容相关联&#xff0c…...

Linux开发必备:Makefile基础与实战模板解析

1. Linux开发中的Makefile基础在Linux环境下开发程序,与Windows平台最大的区别之一就是编译方式。Windows开发者通常习惯使用集成开发环境(IDE)提供的"一键编译"功能,而Linux开发者则需要掌握Makefile这一强大的构建工具。Makefile本质上是一个…...

菜鸟的逆向工程学习之路——逆向工程基本介绍

菜鸟的逆向工程学习之路——逆向工程基本介绍 菜鸟的逆向工程学习之路——逆向工程基本介绍 逆向工程是一种分析目标系统的过程,旨在识别系统的各组件以及组件间关系,以便能够通过其他形式或在较高的抽象层次上,重建系统的表征。 逆向工程一直…...

嵌入式开发中的串口打印调试与printf重定向

1. 为什么需要串口打印调试?在嵌入式开发中,调试手段的选择往往决定了问题排查的效率。使用仿真器(如J-Link、ST-Link)进行单步调试确实是最直观的方式,但在实际项目中经常会遇到以下限制:硬件限制&#xf…...

新手零基础入门:用快马AI生成你的第一个企业网站代码

作为一个刚接触网站开发的新手,我最近尝试用InsCode(快马)平台生成了自己的第一个企业网站代码,整个过程比想象中简单很多。这里记录下我的学习过程和心得,希望能帮到同样零基础的朋友。 理解基础结构 企业网站最基础的单页布局通常包含三个部…...

手把手教你用泰克示波器解码I2C信号(附波形图与常见时序问题排查)

泰克示波器实战:I2C信号解码与时序问题精准定位指南 当一块新开发的电路板躺在实验台上,I2C通信却像被施了沉默咒语般毫无反应——这种场景对硬件工程师来说再熟悉不过。面对SDA和SCL两根看似简单的信号线,隐藏的问题可能来自电平异常、时序偏…...

OpenClaw智能家居中枢:Qwen3-14b_int4_awq语音指令转API调用

OpenClaw智能家居中枢:Qwen3-14b_int4_awq语音指令转API调用 1. 为什么需要本地化智能家居中枢 去年冬天的一个深夜,我被空调突然停止运行的嗡嗡声惊醒。摸索手机查看米家App时,发现服务器维护导致云端控制失效。这次经历让我意识到&#x…...

日志系统整体设计步骤以及功能函数梳理

首先到底要做一个什么东西&#xff1f;我们要造一个 C 高并发异步日志库&#xff0c;功能如下&#xff1a;用 LOG_INFO << "xxx" 这种简单写法自动带&#xff1a;时间、级别、文件名、函数名、行号支持级别过滤&#xff08;TRACE/DEBUG/INFO/WARN/ERROR/FATAL&…...

HWD风速风向传感器Arduino驱动库详解

1. 项目概述 WindSensorHWD_asukiaaa 是一款专为 HWD 系列风速风向传感器设计的嵌入式驱动库&#xff0c;面向 Arduino 及兼容平台&#xff08;如 STM32、ESP32&#xff09;提供标准化、可移植的数据采集接口。该库并非通用串口协议解析器&#xff0c;而是深度适配日本 SigLab …...

evo实战:A-LOAM在KITTI数据集上的多维度性能剖析

1. 从KITTI到ROS&#xff1a;数据格式转换实战 第一次接触KITTI数据集时&#xff0c;我被它那庞大的.bin点云文件搞得一头雾水。作为一个常年和ROS打交道的工程师&#xff0c;我深知bag格式才是SLAM算法的"通用语言"。这里分享一个我验证过的高效转换方案——使用lid…...

软件工程导论简答题速查手册:高频考点+避坑指南(附PDF下载)

软件工程导论高频考点精粹&#xff1a;命题陷阱破解与记忆强化指南 面对软件工程导论考试中纷繁复杂的简答题&#xff0c;许多考生常陷入"知识点背了却不会答题"的困境。这份手册从历年真题大数据中提炼出最高频出现的50个核心考点&#xff0c;采用"命题视角记忆…...

【Hot 100 刷题计划】 LeetCode 45. 跳跃游戏 II | C++ 贪心算法最优解题解

LeetCode 45. 跳跃游戏 II | C 动态规划与贪心 O(N) 双解法题解 &#x1f4cc; 题目描述 题目级别&#xff1a;中等 给定一个长度为 n 的 0 索引整数数组 nums。初始位置在下标 0。 每个元素 nums[i] 表示从索引 i 向后跳转的最大长度。 返回到达 n - 1 的 最小跳跃次数。测试用…...

【Dify】无网络环境下的Dify部署指南:从在线到离线的无缝迁移

1. 为什么需要离线部署Dify&#xff1f; 在企业级应用场景中&#xff0c;数据安全和网络隔离是刚需。很多金融、政务、医疗机构的服务器都部署在内网环境&#xff0c;完全与互联网物理隔离。这时候如果想使用Dify这样的AI应用开发平台&#xff0c;常规的在线安装方式就完全行不…...

002、现代Python后端开发环境与工具链搭建

002、现代Python后端开发环境与工具链搭建 上周排查一个线上问题&#xff0c;日志里报了个ImportError: cannot import name ... from partially initialized module。花了半小时才发现&#xff0c;是同事本地虚拟环境混用了Python 3.8和3.10的依赖&#xff0c;打包时没锁版本。…...

角色如何朝向最近的目标点

将所有目标点添加到数组获取最近的目标...

单线级联可寻址七段数码管设计

1. 项目概述可寻址七段数码管显示模块&#xff08;Addressable Seven Segment Display&#xff09;是一种突破传统驱动架构的嵌入式显示解决方案。其核心设计目标是&#xff1a;仅需单根 GPIO 引脚&#xff0c;即可级联驱动任意数量的七段数码管单元。该方案彻底摒弃了传统数码…...

嵌入式C轻量序列化库:结构体打包与位操作零依赖实现

1. 项目概述dot_util是一个轻量级、零依赖的嵌入式 C 语言工具库&#xff0c;专为资源受限的 MCU&#xff08;如 Cortex-M0/M3/M4、RISC-V 32 位内核&#xff09;设计。其核心定位并非通用算法库或 HAL 封装&#xff0c;而是聚焦于底层数据序列化与结构体操作的工程痛点&#x…...

深入解析CAN报文中的Motorola字节排序:MSB与LSB的实战对比

1. 从汽车仪表盘说起&#xff1a;为什么需要了解CAN字节排序 去年调试一辆新能源车的仪表盘时&#xff0c;我遇到了一个诡异现象&#xff1a;车速显示在80km/h时突然跳变成20km/h。排查三天后发现&#xff0c;问题出在CAN报文解析时搞混了Motorola的MSB和LSB排序方式。这个经历…...

LeetCode--344.反转字符串(字符串/双指针法)

344.反转字符串 题目描述 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须**原地修改输入数组**、使用 O(1) 的额外空间解决这一问题。 示例 1&#xff1a; 输入&#x…...

SAP BP创建供应商主数据保姆级教程:从分组Z005到统驭科目2241039801的完整配置流程

SAP BP供应商主数据创建实战指南&#xff1a;从分组配置到统驭科目设置的深度解析 在SAP系统中&#xff0c;供应商主数据的准确创建是财务和采购业务流程的基石。不同于传统的供应商创建方式&#xff0c;BP&#xff08;Business Partner&#xff09;事务码提供了一种更为统一和…...

大麦APP抢票协议分析:从‘掌密网络’代码看移动端API安全防护

大麦APP抢票协议安全防护体系深度解析 1. 移动端API安全防护的现状与挑战 在移动互联网时代&#xff0c;API作为应用与服务器通信的核心通道&#xff0c;其安全性直接关系到业务系统的稳定性和用户数据的安全。大麦APP作为国内领先的票务平台&#xff0c;面临着巨大的抢票压力和…...

标准、规范、规程有何区别与联系

标准、规范、规程有何区别与联系什么是标准&#xff1a;标准作为标准化的核心&#xff0c;其定义和解释也经历了一个较长的发展时期&#xff0c;最有影响的有三个&#xff1a;一是1934年盖拉德在其《工业标准化原理与应用》一书中对标准所作的定义&#xff0c;这也是世界上最早…...

项目管理实战:如何用关键路径算法优化你的开发周期(附Python代码示例)

项目管理实战&#xff1a;如何用关键路径算法优化你的开发周期&#xff08;附Python代码示例&#xff09; 在敏捷开发团队中&#xff0c;最常听到的抱怨莫过于"时间不够用"。上周我们的跨平台应用项目就遇到了典型困境&#xff1a;产品经理要求三周内完成支付模块重构…...

避雷针保护范围计算公式

避雷针保护范围计算公式 Rx=√H(2Hr-H)-√Hx(2Hr-Hx) Rd=√H(2Hr-H) 其中: Rx---避雷针在Hx高度平面上的保护半径M Hr---滚球半径M Hx---被保护物体高度M H---避雷针的计算高度M Rd---避雷针在地面上的保护半径M Rx=1.6Ha/(1+Hx/H) Rx---避雷针在Hx高度平面上的保护…...

石油干线管道关键参数稳定自动控制系统(CAP)研究

石油干线管道关键参数稳定自动控制系统(CAP)研究 摘要 石油干线管道是国家能源输送的重要基础设施,其运行过程中的压力、流量等关键参数的稳定控制直接关系到管道的安全性与经济性。本文针对石油干线管道参数控制的非线性、大滞后、强耦合等特点,设计并实现了一套关键参数…...

嵌入式蜂鸣器非阻塞管理库BuzzerManager深度解析

1. BuzzerManager 库深度解析&#xff1a;面向嵌入式系统的多路无阻塞蜂鸣器管理方案在嵌入式系统开发中&#xff0c;声音反馈是人机交互最基础、最可靠的物理通道之一。从工业设备的状态提示、医疗仪器的报警响应&#xff0c;到消费电子的按键确认、玩具的音效反馈&#xff0c…...

手把手教你用逻辑分析仪抓取并解析MIPI-CSI-2数据包(以RAW10格式为例)

手把手教你用逻辑分析仪抓取并解析MIPI-CSI-2数据包&#xff08;以RAW10格式为例&#xff09; 在嵌入式视觉系统的开发中&#xff0c;MIPI-CSI-2协议的数据流就像是一条暗河——虽然知道它的存在&#xff0c;但水面下的实际传输细节往往难以窥见。当摄像头输出的图像出现断层、…...

【NLP实战指南】FUNSD数据集:表单理解与结构化数据生成的挑战与机遇

1. FUNSD数据集&#xff1a;表单理解领域的"硬骨头" 第一次接触FUNSD数据集时&#xff0c;我被它满屏的噪点和五花八门的表单样式震惊了。这就像给你一堆被咖啡渍浸过的快递单、皱巴巴的申请表和模糊的扫描件&#xff0c;要求你准确提取所有信息。这个由199份真实扫描…...

Settingator:嵌入式参数管理库的轻量级设计与实践

1. Settingator 库概述&#xff1a;嵌入式设备与移动端配置协同的工程实践Settingator 是一个面向嵌入式系统的轻量级 Arduino 兼容库&#xff0c;其核心目标并非提供通用通信协议栈&#xff0c;而是构建一套可验证、可回滚、低侵入的运行时参数管理机制&#xff0c;专为配合同…...

linux学习进展 基础命令 vi基础命令

Linux系统的核心操作依赖命令行&#xff0c;掌握基础命令是入门Linux的关键&#xff0c;而vi编辑器作为Linux自带的文本编辑工具&#xff0c;日常使用频率极高。本次笔记主要记录Linux常用基础命令及vi编辑器的核心操作&#xff0c;方便后续复习巩固&#xff0c;兼顾实用性和易…...