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

Java日志脱敏——基于logback MessageConverter实现

背景简介

日志脱敏 是常见的安全需求,最近公司也需要将这一块内容进行推进。看了一圈网上的案例,很少有既轻量又好用的轮子可以让我直接使用。我一直是反对过度设计的,而同样我认为轮子就应该是可以让人拿去直接用的。所以我准备分享两篇博客分别实现两种日志脱敏方案。

方案分析

  • logback MessageConverter + 正则匹配本篇博客主要介绍此方法

    • 优势
      • 侵入性低、工作量极少, 只需要修改xml配置文件,适合老项目
    • 劣势
      • 效率低,会对每一行日志都进行正则匹配检查,效率受日志长度影响,日志越长效率越低,影响日志吞吐量
      • 因基于正则匹配 存在错杀风险,部分内容难以准确识别
  • fastjson Filter + 注解 + 工具类下一篇博客介绍 传送门:Java日志脱敏(二)

    • 优势
      • 性能损耗低、效率高、扩展性强,精准脱敏,适合QPS较高日志吞吐量较大的项目。
    • 劣势
      • 侵入性较高,需对所有可能的情况进行脱敏判断
      • 存在漏杀风险,全靠开发控制

其实还有一种方案,基于 工具类+配置模式
优势是 工作量低(比注解模式低,比正则匹配模式高),灵活度高,性能也好。但是只适合那些新项目,如果是老项目大家命名不规范,就很难推动整改了。此处不进行扩展。详见:项目日志脱敏

logback MessageConverter + 正则匹配

流程图解

在这里插入图片描述

代码案例

正则匹配日志脱敏工具类

此工具类主要用于实现依据配置的正则匹配规则集,进行依次匹配。并提取敏感文本对其执行对应的脱敏策略。大家拿去用可以不做修改

package com.zhibo.log.format;import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*** @Author: Zhibo.lv* @Description: 正则匹配日志脱敏工具类**/
@Component
public class LogSensitiveUtils {// 脱敏日志最大长度,超出此长度的日志放弃脱敏,直接返回private static Integer SENSITIVE_LOG_MAX_LENGTH = 10000;/*** 日志脱敏 获取规则集进行依次匹配* @param content 明文日志文本* @return 脱敏后的日志文本*/public static String filterSensitive(String content) {try {if (StringUtils.isNotBlank(content) && content.length() < SENSITIVE_LOG_MAX_LENGTH) {for (Map.Entry<String, List<Pattern>> entry : LogSensitiveConstants.SENSITIVE_SEQUENCE.entrySet()) {content = filter(content, entry.getKey(), entry.getValue());}}return content;} catch (Exception e) {return content;}}/**** @param content   需脱敏字符串* @param type      文本类型,依据类型可以做不同的脱敏方式* @param patterns  该方式下需匹配的正则* @return**/public static String filter(String content, String type, List<Pattern> patterns) {for (Pattern pattern : patterns) {Matcher matcher = pattern.matcher(content);StringBuffer sb = new StringBuffer();while (matcher.find()) {matcher.appendReplacement(sb, Matcher.quoteReplacement(baseSensitive(matcher.group(), type)));}matcher.appendTail(sb);content = sb.toString();}return content;}/*** 依据正则抓去的文本执行对应的脱敏策略* @param str 待脱敏的字符串* @return*/private static String baseSensitive(String str, String type) {if (StringUtils.isBlank(str)) {return StringUtils.EMPTY;}//通过工厂获取对应类型的脱敏类执行脱敏方法return SensitiveStrategyBuiltInUtil.getStrategy(type).des(str);}
}
正则匹配日志脱敏常量

此工具类主要是进行配置需要脱敏的文本的正则。需要大家依据业务调整或新增

package com.zhibo.log.format;import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.regex.Pattern;/*** @Author: Zhibo* @Description: 正则匹配日志脱敏常量**/
public class LogSensitiveConstants {/*** 过滤先后顺序:身份证 -> 手机号* 顺序原因:避免部分业务需求出现可能同时满足多个正则规则的文本,大家可以优先提取更长的、更复杂的文本。后处理简单的*/public static final Map<String,List<Pattern>> SENSITIVE_SEQUENCE = new TreeMap<String, List<Pattern>>();/*** 手机号匹配规则集,支持配置多个正则规则*/public static final List<Pattern> SENSITIVE_PHONE_KEY = new ArrayList<Pattern>(1);/*** 身份证号码匹配规则集,支持配置多个正则规则*/public static final List<Pattern> SENSITIVE_ID_NO_KEY = new ArrayList<Pattern>(1);/*** 手机号正则匹配,11位1开头数字* 瞻前顾后:校验符合要求的文本前后均不能为数字 避免误匹配*/public static final String PHONE_REGEX = "(?<!\\d)[1][3-9][0-9]{9}(?!\\d)";/*** 身份证号正则匹配 18位数版本* 15位数的身份证号码暂不考虑,如果需要自行新增下方正则加入 SENSITIVE_ID_NO_KEY 中* (?<!\d)([1-9]\d{7}((0\d)|(1[0-2]))(([0|1|2]\d)|3[0-1])\d{3})(?!\d)* 瞻前顾后:校验符合要求的文本前后均不能为数字 避免误匹配*/public static final String ID_NO_REGEX = "(?<!\\d)([1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X))(?!\\d)";static {SENSITIVE_ID_NO_KEY.add(Pattern.compile(ID_NO_REGEX));SENSITIVE_PHONE_KEY.add(Pattern.compile(PHONE_REGEX));}// 脱敏替代字符public static final char STAR = '*';// 手机号类型脱敏替代字符public static final String PHONE_MASK = "****";/** 手机号码脱敏策略 */public static final String STRATEGY_PHONE = "strategyPhone";/** 身份证号码脱敏策略 */public static final String STRATEGY_ID_NO = "strategyIdNo";static {//将每一个规则集绑定一个对应的类型SENSITIVE_SEQUENCE.put(STRATEGY_ID_NO, SENSITIVE_ID_NO_KEY);SENSITIVE_SEQUENCE.put(STRATEGY_PHONE, SENSITIVE_PHONE_KEY);}private LogSensitiveConstants() {}
}
脱敏策略代码

定义文本脱敏接口 IStrategy

package com.zhibo.log.sensitive.api;/*** @Author: Zhibo* @Description: 脱敏策略*/
public interface IStrategy {/*** 脱敏* @param original 原始内容* @return 脱敏后的字符串*/String des(final Object original);
}

文本脱敏抽象类,进行通用实现 AbstractStringStrategy

package com.zhibo.log.sensitive.core.strategory;import com.zhibo.log.sensitive.api.IStrategy;
import com.zhibo.log.format.LogSensitiveConstants;import java.security.MessageDigest;/*** @Author: zhibo* @Description: 抽象字符串策略,* 				支持在脱敏后的文本后面追加明文的MD5加密串,方便研发进行日志查询使用*/
public abstract class AbstractStringStrategy implements IStrategy {/*** 获取掩码之前的长度* @param original 原始* @param chars 字符串* @return 结果*/protected abstract int getBeforeMaskLen(Object original, char[] chars);/*** 获取掩码之后的长度* @param original 原始* @param chars 字符串* @return 结果*/protected abstract int getAfterMaskLen(Object original, char[] chars);/*** 针对固定长度的加密直接返回脱敏字符串,避免StringBuilder循环拼接* @return 脱敏字符串*      如返回null 则通过 {@link AbstractStringStrategy#getBeforeMaskLen(Object, char[])} 与 {@link AbstractStringStrategy#getAfterMaskLen(Object, char[])}*      进行截取字符串*/protected String getMask(){return null;}/*** 是否需要拼接MD5密文方便日志查询。* @return false : 不拼接(默认)*          true :  拼接密文 用于日志查询 格式  [MD5]*/protected Boolean addMD5(){return false;}@Overridepublic String des(Object original) {if(original == null) {return null;}String strValue = original.toString();char[] chars = strValue.toCharArray();int beforeMaskLen = getBeforeMaskLen(original, chars);int afterMaskLen = getAfterMaskLen(original, chars);//范围纠正int maxLen = chars.length;beforeMaskLen = Math.min(beforeMaskLen, maxLen);afterMaskLen = Math.min(afterMaskLen, maxLen);StringBuilder stringBuilder = new StringBuilder();//获取明文前缀if(beforeMaskLen > 0) {stringBuilder.append(chars, 0, beforeMaskLen);}//获取脱敏字符串String mask = getMask();if (null == mask){//如未指定脱敏字符串则按规则循环拼接// 中间使用掩码for(int i = beforeMaskLen; i < chars.length - afterMaskLen; i++) {stringBuilder.append(LogSensitiveConstants.STAR);}}else {stringBuilder.append(mask);}//获取明文后缀if(afterMaskLen > 0) {stringBuilder.append(chars, chars.length - afterMaskLen, afterMaskLen);}if (addMD5()){addMD5(strValue,stringBuilder);}return stringBuilder.toString();}// MD5加密private void addMD5(String originalString,StringBuilder stringBuilder) {try {MessageDigest md = MessageDigest.getInstance("MD5");md.update(originalString.getBytes());byte[] digest = md.digest();stringBuilder.append("[");for (byte b : digest) {stringBuilder.append(String.format("%02x", b));}stringBuilder.append("]");} catch (Exception e) {e.printStackTrace();}}
}

身份证脱敏策略实现 StrategyIdNo

package com.zhibo.log.sensitive.core.strategory;/*** @Author: Zhibo* @Description: 身份证号脱敏* 脱敏规则:保留前6 后4 位,其它由星号替换*/
public class StrategyIdNo extends AbstractStringStrategy {@Overrideprotected int getBeforeMaskLen(Object original, char[] chars) {return 6;}@Overrideprotected int getAfterMaskLen(Object original, char[] chars) {return 4;}
}

手机号码脱敏策略实现 StrategyPhone

package com.zhibo.log.sensitive.core.strategory;import com.zhibo.log.format.LogSensitiveConstants;/*** @Author: zhibo* @Description: 手机号脱敏* 脱敏规则:186****8567[MD5]*/
public class StrategyPhone extends AbstractStringStrategy {@Overrideprotected int getBeforeMaskLen(Object original, char[] chars) {return 3;}@Overrideprotected int getAfterMaskLen(Object original, char[] chars) {return 4;}@Overrideprotected String getMask() {return LogSensitiveConstants.PHONE_MASK;}@Overrideprotected Boolean addMD5(){return true;}
}
logback 消息转换器实现

最关键的方法来啦

package com.zhibo.log.format;import ch.qos.logback.classic.pattern.MessageConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;/*** @Author: Zhibo* @Description: 日志脱敏转换器**/
public class SensitiveConverter extends MessageConverter {@Overridepublic String convert(ILoggingEvent event){// 获取原始日志String requestLogMsg = super.convert(event);// 执行日志脱敏return LogSensitiveUtils.filterSensitive(requestLogMsg);}public SensitiveConverter() {}
}

自此我们的工具包也就完成了,业务系统需要使用此工具只需要修改resources目录下的logback.xml配置。

<!-- 新增或修改原有消息转换器为SensitiveConverter -->
<conversionRule conversionWord="msgToo" converterClass="com.zhibo.log.format.SensitiveConverter" />

并将文件输出日志的消息内容替换为指定消息转换器的 conversionWord
在这里插入图片描述

脱敏效果展示

在这里插入图片描述

有请提示

注:此方法对日志吞吐量存在影响,由于正则需要循环匹配整个日志文本,所以正则规则越多,日志文本越长,耗时越长。如您的应用程序对日志吞吐量要求较高且存在大量超长日志文本请压测后使用。

如配置了logback的异步打印,且设置了允许日志丢弃,在压测中可能出现因线程池与等待队列均被占满而导致日志丢失情况。下面是我的问题复盘:

logback日志异步打印配置如下

<appender name="ASYNC-FILE" class="ch.qos.logback.classic.AsyncAppender"><neverBlock>true</neverBlock><!-- 非阻塞方式运行 如队列满就开始丢弃日志 --><queueSize>1024</queueSize><!-- 等待队列大小 --><discardingThreshold>0</discardingThreshold><!-- 日志队列深度,配置0 队列满后丢弃最老的日志 --><appender-ref ref="FILE"/>
</appender>

以上配置 为logback线程池工作配置,默认线程池 线程数为 10个,最大队列长度为1024个。
意味着如果日志产生的速度超过10个线程工作处理日志的速度,则无法处理的日志会被写入BlockingQueue 队列,当队列满了之后就会导致日志丢失的情况。

继续阅读:Java日志脱敏(二)——fastjson Filter + 注解 + 工具类实现

相关文章:

Java日志脱敏——基于logback MessageConverter实现

背景简介 日志脱敏 是常见的安全需求&#xff0c;最近公司也需要将这一块内容进行推进。看了一圈网上的案例&#xff0c;很少有既轻量又好用的轮子可以让我直接使用。我一直是反对过度设计的&#xff0c;而同样我认为轮子就应该是可以让人拿去直接用的。所以我准备分享两篇博客…...

在 Ubuntu 22.04 上部署Apache 服务, 访问一张照片

要在 Ubuntu 22.04 上部署一张照片&#xff0c;使其可以通过 Apache 访问&#xff0c;你可以按照以下步骤进行操作&#xff1a; 1. 安装 Apache&#xff08;如果尚未安装&#xff09; 如果你还没有安装 Apache&#xff0c;可以使用以下命令&#xff1a; sudo apt update sud…...

从0学习React(10)

示例代码&#xff1a; const columns: ProColumns<API.BasicInfoItem>[] [{title: 设备编码,dataIndex: deviceCode,ellipsis: true,width: 40,},{title: 设备名称,dataIndex: deviceName,ellipsis: true,width: 50,},{title: 产线-工序,dataIndex: deviceClassifyName…...

Redis-结构化value对象的类型

文章目录 一、Redis的结构化value对象类型的介绍二、Redis的这些结构化value对象类型的通用操作查看指定key的数据类型查看所有的key判断指定key是否存在为已存在的key进行重命名为指定key设置存活时间pexpire与expire 查看指定Key的存活时间为指定key设置成永久存活 三、Redis…...

【QT】Qt对话框

个人主页~ Qt窗口属性~ Qt窗口 五、对话框2、Qt内置对话框&#xff08;1&#xff09;Message Box&#xff08;2&#xff09;QColorDialog&#xff08;3&#xff09;QFileDialog&#xff08;4&#xff09;QFontDialog&#xff08;5&#xff09;QInputDialog 五、对话框 2、Qt内…...

【计算机网络篇】数据链路层(14)虚拟局域网VLAN(概述,实现机制)

文章目录 &#x1f6f8;虚拟局域网VLAN&#x1f354;虚拟局域网VLAN的实现机制&#x1f95a;IEEE 802.1Q帧&#x1f95a;以太网交换机的接口类型&#x1f5d2;️例一&#xff1a;在一个交换机上不进行人为的VLAN划分&#xff0c;交换机各接口默认属于VLAN1且类型为Access的情况…...

伺服中的电子凸轮与追剪

一、机械凸轮 机械凸轮是一个具有曲线轮廓或凹槽的构件&#xff0c;它把运动特性传递给紧靠其边缘移动的推杆&#xff0c;推杆又带动机架做周期性运动。 凸轮的推杆位置跟随凸轮角度的周期性变化而变化&#xff0c;其运动特性与机械凸轮的外形相关&#xff0c;定义凸轮…...

Oracle 第22章:数据仓库与OLAP

第22章&#xff1a;数据仓库与OLAP 1. 数据仓库概念 数据仓库&#xff08;Data Warehouse, DW&#xff09; 是一个面向主题的、集成的、相对稳定的、反映历史变化的数据集合&#xff0c;用于支持管理决策。数据仓库中的数据通常来自不同的操作型系统或外部数据源&#xff0c;…...

在Ubuntu上安装TensorFlow与Keras

文章目录 1. 查看系统和Python版本信息1.1 查看Ubuntu版本信息1.2 查看Python版本信息 2. 安装pip2.1 下载get-pip.py2.2 运行get-pip.py2.3 查看pip版本 3. 安装Jupyter Notebook3.1 安装Jupyter Notebook3.2 运行Jupyter Notebook3.3 安装jupyter-core3.4 配置Jupyter Notebo…...

vue data变量之间相互赋值或进行数据联动

摘要&#xff1a; 使用vue时开发会用到data中是数据是相互驱动&#xff0c;经常会想到watch,computed&#xff0c;总结一下&#xff01; 直接赋值&#xff1a; 在 data 函数中定义的变量可以直接在方法中进行赋值。 export default {data() {return {a: 1,b: 2};},methods: {u…...

如何理解ref,toRef,和toRefs

1. ref ref 是 Vue 3 提供的一个用于创建响应式数据的 API。它可以用来创建简单的响应式变量&#xff0c;例如数字、字符串、布尔值或对象等。通过使用ref&#xff0c;当数据发生变化时&#xff0c;相关的组件视图会自动更新。 用法 创建响应式数据&#xff1a; import { ref …...

从单一到多元:揭秘 Hexo Diversity 主题的运行原理

揭秘 Hexo Diversity 主题的运行原理 一、 引言二、 Diversity 主题2.1 Hexo 控制台命令2.2 Hexo 核心 API2.3 运行原理2.3.1 多主题配置相关2.3.2 多主题执行指令 2.4 版本演进2.4.1 V1版本2.4.2 V2版本2.4.2.1 PC 端2.4.2.2 Phone 端 2.5 后续展望 三、 总结 一、 引言 众所…...

软考中级(系统集成项目管理工程师)案例分析计算题-笔记

案例分析计算题必拿分&#xff01;&#xff01; 1.成本进度管理 初中数学题&#xff0c;整了一堆缩写&#xff0c;容易给人绕晕 知道英文全称后就好理解了名词汇总&#xff1a; 英文缩写英文全称含义公式PVPlanned Value (计划值)按照计划到当前时间点需要花费的钱根据题目自…...

Docker打包自己项目推到Docker hub仓库(windows10)

一、启用Hyper-V和容器特性 1.应用和功能 2.点击程序和功能 3.启用或关闭Windows功能 4.开启Hyper-V 和 容器特性 记得重启生效&#xff01;&#xff01;&#xff01; 二、安装WSL2&#xff1a;写文章-CSDN创作中心https://mp.csdn.net/mp_blog/creation/editor/143057041 三…...

CesiumJS 案例 P20:监听鼠标滚轮、监听鼠标左键按下与松开、监听鼠标右键按下与松开、监听鼠标左击落点

CesiumJS CesiumJS 是一个开源的 JavaScript 库&#xff0c;它用于在网页中创建和控制 3D 地球仪&#xff08;地图&#xff09; CesiumJS 官网&#xff1a;https://www.cesium.com/ CesiumJS 下载地址&#xff1a;https://www.cesium.com/platform/cesiumjs/ CesiumJS API 文…...

如何使用Web-Check和cpolar实现安全的远程网站监测与管理

文章目录 前言1.关于Web-Check2.功能特点3.安装Docker4.创建并启动Web-Check容器5.本地访问测试6.公网远程访问本地Web-Check7.内网穿透工具安装8.创建远程连接公网地址9.使用固定公网地址远程访问 前言 本期给大家分享一个网站检测工具Web-Check&#xff0c;能帮你全面了解网…...

随机生成100组N个数并对比,C++,python,matlab,pair,std::piecewise_construct

随机生成100组N个数&#xff0c;数的范围是1到35&#xff0c;并检查是否包含目标数组的数字 python版本 import numpy as np def count_groups_containing_obj(N, obj):# 随机生成100组N个数&#xff0c;数的范围是1到35groups np.random.randint(1, 36, size(1000, N))#pri…...

python爬虫获取数据后的数据提取

文章目录 python爬虫中的数据提取1.Json格式数据的数据提取2.Html格式数据提取之bs4解析器如何使用快速使用对象的种类Tagname和attributes属性NavigableString(字符串)BeautifulSoupComment 子节点.contents.children.descendants 父节点.parent.parents 节点内容.string.stri…...

前段(vue)

目录 跨域是什么&#xff1f; SprinBoot跨域的三种解决方法 JavaScript 有 8 种数据类型&#xff0c; 金额的用什么类型。 前段 区别 JQuery使用$.ajax()实现异步请求 Vue 父子组件间的三种通信方式 Vue2 和 Vue3 存在多方面的区别。 跨域是什么&#xff1f; 跨域是指…...

pairwise算法之rank svm

众所周知&#xff0c;point-wise/pair-wise/list-wise是机器学习领域中重要的几种建模方法。比如&#xff0c;最常见的分类算法使用了point-wise&#xff0c;即一条样本对应一个label(0/1)&#xff0c;根据多条正负样本&#xff0c;使用交叉熵&#xff08;cross entropy&#x…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

CVPR 2025 MIMO: 支持视觉指代和像素grounding 的医学视觉语言模型

CVPR 2025 | MIMO&#xff1a;支持视觉指代和像素对齐的医学视觉语言模型 论文信息 标题&#xff1a;MIMO: A medical vision language model with visual referring multimodal input and pixel grounding multimodal output作者&#xff1a;Yanyuan Chen, Dexuan Xu, Yu Hu…...

脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)

一、数据处理与分析实战 &#xff08;一&#xff09;实时滤波与参数调整 基础滤波操作 60Hz 工频滤波&#xff1a;勾选界面右侧 “60Hz” 复选框&#xff0c;可有效抑制电网干扰&#xff08;适用于北美地区&#xff0c;欧洲用户可调整为 50Hz&#xff09;。 平滑处理&…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

视频字幕质量评估的大规模细粒度基准

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用&#xff0c;因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型&#xff08;VLMs&#xff09;在字幕生成方面…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...