node.js基础学习-JWT登录鉴权(十四)
一、前言
JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在各方之间安全地传输信息。它本质上是一个字符串,由三部分组成:头部(Header)、载荷(Payload)和签名(Signature)。这三个部分通过 “.” 连接,形成一个完整的 JWT,例如:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
。
二、JWT组成部分
-
头部(Header):
-
主要包含两部分信息,令牌的类型(通常是 “JWT”)和所使用的签名算法(如 HMAC SHA256、RSA 等)。例如,一个典型的头部可能是
{"alg": "HS256", "typ": "JWT"}
,这个头部经过 Base64Url 编码后就成为 JWT 的第一部分。 -
作用是告诉接收方这个令牌的基本信息,包括如何验证它的签名。
-
载荷(Payload):
-
这部分包含了实际要传输的信息,也被称为声明(Claims)。这些声明可以是预定义的(如 “iss” - 令牌发行者、“sub” - 主题、“aud” - 受众、“exp” - 过期时间、“nbf” - 在此日期之前不可用),也可以是自定义的。例如,
{"sub": "1234567890", "name": "John Doe", "iat": 1516239022}
,这里的 “sub” 可能代表用户的唯一标识,“name” 是用户名称,“iat” 是令牌发布时间。 -
经过 Base64Url 编码后成为 JWT 的第二部分,用于在不同系统之间传递一些必要的用户或业务相关的数据,同时不会像在纯文本中那样容易被篡改。
-
签名(Signature):
-
签名是通过对头部和载荷进行特定算法运算得到的。首先将头部和载荷分别进行 Base64Url 编码,然后使用头部中指定的签名算法(如 HS256),结合一个只有服务器知道的密钥(Secret),对编码后的头部和载荷进行签名计算。例如,对于 HS256 算法,签名计算公式可能是
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
。 -
签名的作用是确保 JWT 的完整性和真实性。接收方可以使用相同的算法和密钥来验证签名,从而判断 JWT 在传输过程中是否被篡改。如果签名验证失败,那么这个 JWT 就应该被拒绝。
三、JWT登录鉴权实现过程
1、前端实现过程
1.安装 Axios:
在前端项目的根目录下,打开终端并执行 npm install axios 命令。
2. 配置 Axios 拦截器:
请求拦截器(添加 JWT 到请求头):
在 JavaScript 文件(例如 axiosConfig.js
)中,引入 Axios:
import axios from 'axios';
然后设置请求拦截器:
axios.interceptors.request.use((config) => {const token = localStorage.getItem('jwtToken');if (token) {// 如果存在 JWT 令牌,将其添加到请求头的 Authorization 字段,格式为 Bearer <令牌>config.headers.Authorization = `Bearer ${token}`;}// 返回修改后的配置对象,以便 Axios 使用该配置发送请求return config;}, (error) => {// 如果在设置请求头过程中出现错误,直接拒绝该 Promise,将错误传递给调用者return Promise.reject(error);});
响应拦截器(处理 JWT 相关错误):
继续在 axiosConfig.js
文件中设置响应拦截器:
axios.interceptors.response.use((response) => {// 如果响应成功(状态码在 200 - 299 之间),直接返回响应数据return response;}, (error) => {// 检查响应的状态码,如果存在的话const status = error.response? error.response.status : null;if (status === 401 || status === 403) {// 如果状态码是 401(未授权)或 403(禁止访问),表示 JWT 可能过期或无效// 清除本地存储中的 JWT 令牌localStorage.removeItem('jwtToken');// 重定向到登录页面(这里假设使用 React Router,并且已经在组件中获取了路由历史对象 history)const history = useHistory();history.push('/login');}// 将错误重新抛出,以便在调用处进行处理return Promise.reject(error);});
3.登录获取 JWT 并存储:
在登录组件(例如 Login.js
)中,当用户点击登录按钮后,收集用户名和密码,然后使用 Axios 发送 POST 请求到后端的登录接口:
import axios from 'axios';async function login(username, password) {try {const response = await axios.post('http://localhost:3000/login', {username: username,password: password});const token = response.data.token;// 将 JWT 存储在本地存储中localStorage.setItem('jwtToken', token);return token;} catch (error) {console.error('登录出错:', error);throw error;}}
4.处理 JWT 过期自动刷新(可选):
可以设置一个定时器来检查 JWT 的过期时间,并在即将过期时尝试刷新令牌。以下是一个简单示例:
function checkTokenExpiration() {const token = localStorage.getItem('jwtToken');if (token) {const decodedToken = jwt_decode(token);const expirationTime = decodedToken.exp * 1000; // 将过期时间转换为毫秒const currentTime = Date.now();const timeToExpiration = expirationTime - currentTime;// 假设在令牌过期前 5 分钟进行刷新操作if (timeToExpiration < 5 * 60 * 1000) {refreshToken();}}}async function refreshToken() {try {const refreshToken = localStorage.getItem('refreshToken');const response = await axios.post('http://localhost:3000/refresh-token', {refreshToken: refreshToken});const newToken = response.data.token;localStorage.setItem('jwtToken', newToken);} catch (error) {console.error('刷新令牌出错:', error);// 如果刷新令牌失败,可能需要清除令牌并跳转到登录页面localStorage.removeItem('jwtToken');const history = useHistory();history.push('/login');}}// 每隔一段时间检查令牌过期情况setInterval(checkTokenExpiration, 60 * 1000);
这里假设后端有一个 refresh-token
接口用于刷新令牌,并且前端存储了一个 refreshToken
用于刷新操作。同时,使用 jwt_decode
库(需要先安装)来解析 JWT 获取过期时间信息。
5.使用 Axios 发送请求(以获取用户信息为例):
在需要获取用户信息的组件(例如 UserProfile.js
)中,引入 Axios:
import axios from 'axios';
然后发送请求:
axios.get('http://localhost:3000/api/user-info').then((response) => {// 如果请求成功,打印用户信息console.log('用户信息:', response.data);}).catch((error) => {// 如果请求失败,打印错误信息console.error('获取用户信息出错:', error);});
2、后端实现过程
1.安装相关库(以 Node.js 为例):
在后端项目的根目录下,打开终端并执行 npm install jsonwebtoken
命令。
2.设置 JWT 密钥(环境变量):
在开发环境中,对于 Linux 或 macOS 系统,可以在终端中设置环境变量:
export JWT_SECRET=mysecretkey
对于 Windows 系统,可以使用:
set JWT_SEAST=mysecretkey
在生产环境中,通常会使用服务器的环境变量配置功能来设置 JWT_SECRET
。
在后端代码(例如 app.js
)中获取密钥:
const jwtSecret = process.env.JWT_SECRET;
3.用户登录接口(生成 JWT)
假设后端有一个用户模型(例如使用 Mongoose 定义的用户模型),用于验证用户凭据。以下是一个简单的用户登录接口,用于生成 JWT:
const express = require('express');const jwt = require('jsonwebtoken');const User = require('./models/user');const app = express();app.post('/login', async (req, res) => {const {username, password} = req.body;try {const user = await User.findOne({username, password});if (!user) {res.status(401).send('用户名或密码错误');} else {const token = jwt.sign({id: user._id, username: user.username}, jwtSecret, {expiresIn: '1h'});// 生成刷新令牌(可以是一个随机字符串等)const refreshToken = generateRefreshToken(); res.send({token, refreshToken});}} catch (err) {console.error('登录出错:', err);res.status(500).send('内部错误');}});function generateRefreshToken() {// 这里简单返回一个随机字符串作为示例,实际应用中可以更复杂的生成逻辑return Math.random().toString(36).substring(2, 15);}
这个接口首先从请求体中获取用户名和密码,然后在数据库中查找匹配的用户(这里假设 User.findOne
方法用于在数据库中查找用户)。如果找到用户,就使用 jwt.sign
方法生成一个 JWT,有效期为 1 小时,并生成一个刷新令牌,然后将它们发送给前端;如果找不到用户或者出现错误,就返回相应的错误信息。
4.验证 JWT 中间件(保护路由):
为了保护需要认证的后端路由,需要创建一个中间件来验证 JWT。以下是一个简单的中间件示例:
function authenticateToken(req, res, next) {const authHeader = req.headers['authorization'];const token = authHeader && authHeader.split(' ')[1];if (token == null) {return res.status(401).send('未提供认证令牌');}jwt.verify(token, jwtSecret, (err, user) => {if (err) {return res.status(403).send('无效的认证令牌');}req.user = user;next();});}
这个中间件首先从请求头中提取 JWT,然后使用 jwt.verify
方法来验证 JWT 的有效性。如果 JWT 有效,就将用户信息(从 JWT 的载荷部分解析出来的)存储在 req.user
中,并调用 next
函数,允许请求继续处理;如果 JWT 无效或者未提供,就返回相应的错误信息。可以将这个中间件应用到需要认证的路由上,例如:
app.get('/api/user-info', authenticateToken, (req, res) => {res.send('这是一个受保护的路由,只有通过认证的用户才能访问');});
当用户访问 /api/user-info
路由时,首先会经过 authenticateToken
中间件进行 JWT 验证,只有验证通过的用户才能访问该路由的内容。
5.刷新令牌接口(可选):
如果前端实现了令牌刷新功能,后端需要提供一个刷新令牌的接口:
app.post('/refresh-token', (req, res) => {const {refreshToken} = req.body;// 这里需要验证刷新令牌的有效性,例如检查是否在数据库中存在且未过期等if (isRefreshTokenValid(refreshToken)) {const user = getUserFromRefreshToken(refreshToken);const newToken = jwt.sign({id: user._id, username: user.username}, jwtSecret, {expiresIn: '1h'});res.send({token: newToken});} else {res.status(401).send('无效的刷新令牌');}});function isRefreshTokenValid(refreshToken) {// 简单示例,实际应用中需要更完善的验证逻辑return refreshToken.length > 0;}function getUserFromRefreshToken(refreshToken) {// 假设根据刷新令牌可以获取到对应的用户信息,这里简单返回一个示例用户return {id: 1, username: 'exampleUser'};}
这个接口接收前端发送的刷新令牌,验证其有效性,如果有效则生成一个新的 JWT 并返回给前端;如果无效则返回 401 错误。
通过以上前后端的实现过程,不仅实现了基本的 JWT 认证,还包含了令牌生成、存储、过期处理以及刷新等功能,能够构建一个相对完整的用户认证系统。在实际应用中,还需要根据项目的具体需求进一步优化和完善代码,例如加强令牌的安全性、完善数据库操作等。
相关文章:
node.js基础学习-JWT登录鉴权(十四)
一、前言 JWT(JSON Web Token)是一种开放标准(RFC 7519),用于在各方之间安全地传输信息。它本质上是一个字符串,由三部分组成:头部(Header)、载荷(Payload&am…...
AbutionGraph-时序向量图谱数据库-快速安装部署
运行环境 1)操作系统 最好是使用CentOS7或者Ubuntu18以上系统,不满足的话请升级系统内核gcc版本至8以上版本。 支持所有国产主流操作系统银河麒麟、统信OS、深度等等,均做过兼容性测试; 2)CPU 为确保数据库每个进…...
翻译质量差对电子课程用户体验的影响
电子学习改变了教育交付方式,使全球不同受众更容易获得课程。然而,随着这种学习模式的发展,对周到地本地化和翻译的需求也在增长。如果做得好,翻译可以弥合文化和语言分歧,创造无缝和包容的学习体验。然而,…...
PS的功能学习(修复、画笔)
混合器画笔工具 就像,电子毛笔 关键功能有两个,自带一个混合器色板 清理画笔是全清,换一支新的毛笔,执行完之后在判断是否载入画笔 载入画笔就是把前景色上的颜色进行叠加处理,重新混入当前的混合色 (…...
Android 使用 Canvas 和 Paint 实现圆形图片
学习笔记 效果展示: 全部代码: public class YuanActivity extends AppCompatActivity {private ActivityYuanBinding binding;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 通过 DataBinding 获取布局文件binding …...
vxe-table 键盘操作,设置按键编辑方式,支持覆盖方式与追加方式
vxe-table 全键盘操作,按键编辑方式设置,覆盖方式与追加方式; 通过 keyboard-config.editMode 设置按键编辑方式;支持覆盖方式编辑和追加方式编辑 安装 npm install vxe-pc-ui4.3.15 vxe-table4.9.15// ... import VxeUI from v…...
BUUCTF Pwn [HarekazeCTF2019]baby_rop 题解
下载 checksec 64位 用IDA64打开 定位main函数 栈溢出漏洞 SHIFTF12的字符串看到了binsh 以及函数窗口有system 因为是64位 找到rdi传参和ret栈平衡 构造exp: from pwn import *#p process(./babyrop) p remote("node5.buuoj.cn", 27869)addr_prr 0…...
什么是封装性?C++ 中如何实现封装?封装性的好处是什么?
一、引言 在面向对象编程中,封装性是一个重要的概念。封装可以帮助我们更好地组织和管理代码,提高代码的可维护性、可扩展性和安全性。本文将详细介绍什么是封装性,C 中如何实现封装以及封装性的好处。 二、什么是封装性? 封装…...
【MySQL】[42000][1071] Specified key was too long; max key length is 3072 bytes
问题描述 创建表时发生错误。 create table if not exists tbl_user(id int unsigned auto_increment comment 用户IDprimary key,username varchar(1023) not null comment 用户名,password varchar(1023) default 123456 …...
人工智能驱动的骗局会模仿熟悉的声音
由于人工智能技术的进步,各种现代骗局变得越来越复杂。 这些骗局现在包括人工智能驱动的网络钓鱼技术,即使用人工智能模仿家人或朋友的声音和视频。 诈骗者使用来自社交媒体的内容来制作深度伪造内容,要求提供金钱或个人信息。个人应该通过…...
实数与复数频谱掩蔽在音频分离中的应用
使用实数和复数频谱掩蔽进行音频分离 频谱掩蔽是指在音频信号的频谱表示中,通过选择性地增强或抑制某些频率成分来改善信号质量或实现信号分离的技术。频谱掩蔽可以分为两种类型:实数掩蔽和复数掩蔽。 实数频谱掩蔽 实数频谱掩蔽主要关注音频信号的幅…...
C++算法练习-day62——491.非递减子序列
题目来源:. - 力扣(LeetCode) 题目思路分析 这个问题要求找出数组 nums 中的所有非严格递增子序列,其中每个子序列至少包含两个元素。非严格递增子序列意味着子序列中的元素可以相等,但不允许递减。 为了解决这个问…...
golang实现单例日志对象
原文地址:golang实现单例日志对象 – 无敌牛 欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等 介绍 golang有很多日志包,通过设置和修改都能实现日志轮转和自定义日志格式。例如:log、zap、golog、slog、log4go 等等。 …...
Redis——个人笔记留存
今日内容 1. redis1. 概念2. 下载安装3. 命令操作1. 数据结构4. 持久化操作5. 使用Java客户端操作redis Redis 1. 概念: redis是一款高性能的NOSQL系列的非关系型数据库 1.1.什么是NOSQLNoSQL(NoSQL Not Only SQL),意即“不仅仅是SQL”,是…...
c# Grpc取消
net6.0 通过CancellationTokenSource 客户端取消Grpc,服务端判断 IsCancellationRequested 是否取消。 proto: syntax "proto3";// 引用可空类型 import "google/protobuf/wrappers.proto";option csharp_namespace "Grpc.Common"…...
Flask 是什么?
近期开发chatbot 程序,过程中要使用Flask,所以收集资料记录这个套件的信息: Flask 是什么? Flask 是一个轻量级、模块化的 Python Web 框架,用于构建 Web 应用程序和 API。它被设计为简单、灵活且可扩展,…...
智能合约
06-智能合约 0 啥是智能合约? 定义 智能合约,又称加密合约,在一定条件下可直接控制数字货币或资产在各方之间转移的一种计算机程序。 角色 区块链网络可视为一个分布式存储服务,因为它存储了所有交易和智能合约的状态 智能合约还…...
【机器学习】分类器
在机器学习(Machine Learning,ML)中,分类器泛指算法或模型,用于将输入数据分为不同的类别或标签。分类器是监督学习的一部分,它依据已知的数据集中的特征和标签进行训练,并根据这些学习到的知识对新的未标记数据进行分…...
ASP 快速参考
ASP 快速参考 概述 ASP(Active Server Pages)是一种由微软开发的服务器端脚本环境,用于动态生成交互性网页。它允许开发者结合HTML、VBScript或JScript脚本语言来创建和运行动态网页或Web应用程序。本快速参考将提供ASP的基础知识、常用内置…...
支持向量机算法:原理、实现与应用
摘要: 本文深入探讨支持向量机(Support Vector Machine,SVM)算法,详细阐述其原理、数学模型、核函数机制以及在分类和回归问题中的应用方式。通过以 Python 和 C# 为例,展示 SVM 算法在不同编程环境下的具体…...
蓝桥杯分治
P1226 【模板】快速幂 题目描述 给你三个整数 𝑎,𝑏,𝑝a,b,p,求 𝑎𝑏 mod 𝑝abmodp。 输入格式 输入只有一行三个整数,分别代表 𝑎,𝑏,𝑝a,b,p。…...
群控系统服务端开发模式-应用开发-邮件工厂结构封装
首先在系统根目录下extend文件夹下创建邮件工厂文件夹并更名叫Mail。 一、邮件发送父类 在Mail目录下创建邮件发送父类并更名为MailSenderInterface.php,代码如下 <?php /*** 邮件发送父类* User: 龙哥三年风水* Date: 2024/12/5* Time: 14:22*/ namespace Ma…...
COCO数据集理解
COCO(Common Objects in Context)数据集是一个用于计算机视觉研究的广泛使用的数据集,特别是在物体检测、分割和图像标注等任务中。COCO数据集由微软研究院开发,其主要特点包括: 丰富的标签:COCO数据集包含…...
数据结构与算法学习笔记----堆
数据结构与算法学习笔记----堆 author: 明月清了个风 first publish time: 2024.12.2 revised: 2024.12.3 - 例题标题错误,已修改。 ps⛹从这里开始调整了文章结构,先讲解算法和数据结构基本原理,再给出例题,针对例题中的应用再…...
在玩“吃鸡”的时候游戏崩溃要如何解决?游戏运行时崩溃是什么原因?
“吃鸡”游戏崩溃问题深度解析与解决方案:原因、修复与预防 在紧张刺激的“吃鸡”(即《绝地求生》)游戏中,突然遭遇游戏崩溃无疑会让玩家倍感沮丧。作为一名经验丰富的软件开发从业者,我深知游戏崩溃可能由多种因素引…...
AndroidAutoSize实战教程:今日头条屏幕适配方案详解
如何在项目中结合 AndroidAutoSize 来进行今日头条屏幕适配,我会具体讲解如何用 AndroidAutoSize 实现屏幕适配,并结合 Kotlin 代码举例分析。 通过 AndroidAutoSize 库来实现屏幕适配,确保在不同的屏幕尺寸、分辨率、密度下,应用…...
学习threejs,通过设置纹理属性来修改纹理贴图的位置和大小
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️Texture 贴图 二、…...
图生3d 图生全景 学习笔记
目录 Aluciddreamer ZoeDepth 会自动下载模型: 图生全景图SD-T2I-360PanoImage: Aluciddreamer GitHub - luciddreamer-cvlab/LucidDreamer: Official code for the paper "LucidDreamer: Domain-free Generation of 3D Gaussian Splatting Sce…...
Delphi 实现键盘模拟、锁定键盘,锁定鼠标等操作
Delphi 模拟按键的方法 SendMessageA 说明: 调用一个窗口的窗口函数,将一条消息发给那个窗口。除非消息处理完毕,否则该函数不会返回SendMessage所包含4个参数: 1. hwnd 32位的窗口句柄窗口可以是任何类型的屏幕对象,因为Win32能够维护大多数…...
6. 一分钟读懂“抽象工厂模式”
6.1 模式介绍 书接上文,工厂方法模式只能搞定单一产品族,遇到需要生产多个产品族时就歇菜了。于是,在需求的“花式鞭策”下,程序员们再次绷紧脑细胞,创造出了更强大的抽象工厂模式,让工厂一次性打包多个产品…...
(四)lerobot开源项目的主从臂的远程操作(带相机)(操作记录)
目录 《项目简介》 一、B站视频参考(推荐) 二、确定两个usb相机的端口号 三、远程操作(带相机) 四、遇到问题 《项目简介》 项目地址:GitHub - huggingface/lerobot: 🤗 LeRobot: Making AI for Ro…...
离线安装ollama到服务器
搜了很多教程不满意,弄了半天才弄好,这里记录下,方便以后的人用,那个在线下载太慢,怕不是得下载到明年。 一.从官网下在liunx版的tgz安装包 Releases ollama/ollama (github.com) 查看自己的服务器信息(参考 https:/…...
Vue前端开发-多级路由配置
在Vue 路由数组中,允许配置多级的路由对象结构,可以是二级、三级或者更多级别,最大级别原则上没有限制,但通常最大的是三或四级,这种路由结构,称之为多级路由。 例如:一级路由地址/list&#x…...
Yocto bitbake and codeSonar
1 mdm 1.1 屏蔽mdm sysvinit的console输出 - uboot传入参数的时候传入consolenull,这样Linux启动信息没有了 - 还需要在Linux配置中去掉Support for console on AMBA serial port - 文件系统/etc/inittab文件里注释掉::respawn:/sbin/getty -L ttyS000 115200 vt100…...
sheng的学习笔记-【中】【吴恩达课后测验】Course 5 -序列模型 - 第二周测验 - 自然语言处理与词嵌入
课程5_第2周_测验题 目录 第一题 1.假设你为10000个单词学习词嵌入,为了捕获全部范围的单词的变化以及意义,那么词嵌入向量应该是10000维的。 A. 【 】正确 B. 【 】错误 答案: B.【 √ 】错误 第二题 2.什么是t-SNE?…...
数字图像处理内容详解
1.对比度 最大亮度 / 最小亮度 2.邻域 m邻接:对于像素p和q,如果p和q四临接,或p和q八临接且两者的四邻域的交集为空 通路:如果俩点全部是K邻接(K代表4,8,m),则说明存在K…...
python通过ODBC连接神通数据库
1、安装神通数据库 2、安装python 3、安装pyodbc pip3 install pyodbc-5.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl 注:pyodbc要和python版本相对应 4、安装unixodbc 5、配置神通数据库ODBC数据源 6、示例代码如下 #!/usr/bin/python…...
QNX的PPS发布/订阅模型
参考资料: QNX官方文档 以下摘自官网介绍: TheQNX NeutrinoPersistent Publish/Subscribe (PPS) service is a small, extensible publish/subscribe service that offers persistence across reboots. It’s designed to provide a simple and easy-to-use solution for b…...
Ubuntu——extrepo添加部分外部软件源
extrepo 是一个用于 Ubuntu 和其他基于 Debian 的系统的工具,它的主要作用是简化和管理外部软件源(repositories)的添加和更新。通过使用 extrepo,用户可以方便地添加、删除和管理第三方软件源,而不需要手动编辑源列表…...
java基础教程第16篇( 正则表达式)
Java 正则表达式 正则表达式定义了字符串的模式。 正则表达式可以用来搜索、编辑或处理文本。 正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。 Java 提供了 java.util.regex 包,它包含了 Pattern 和 Matcher 类,用于处理正…...
【Shell 脚本实现 HTTP 请求的接收、解析、处理逻辑】
以下是一个实现客户端对 Shell HTTP 服务发起 POST 请求并传入 JSON 参数的完整示例。Shell 服务会解析收到的 JSON 数据,根据内容执行操作。 服务端脚本:http_server.sh 以下脚本使用 netcat (nc) 来监听 HTTP 请求,并通过 jq 工具解析 JSO…...
Leetcode 每日一题 290.单词规律
目录 一、问题分析 二、解题思路 三、代码实现 四、复杂度分析 五、总结 在编程的世界里,我们常常会遇到各种有趣的字符串匹配问题。今天要探讨的就是这样一个问题:给定一种规律 pattern 和一个字符串 s,判断 s 是否遵循与 pattern 相同…...
图像滤波和卷积的不同及MATLAB应用实例
滤波与卷积在图像处理中都是非常重要的运算,但它们有着明显的区别。以下是滤波与卷积的主要不同点,并附带一个MATLAB实例来展示两者在图像处理中的效果差异。 一、滤波与卷积的不同 定义与目的: 1)滤波:滤波是一种信…...
【AI模型对比】AI新宠Kimi与ChatGPT的全面对比:技术、性能、应用全揭秘
文章目录 Moss前沿AI技术背景Kimi人工智能的技术积淀ChatGPT的技术优势 详细对比列表模型研发Kimi大模型的研发历程ChatGPT的发展演进 参数规模与架构Kimi大模型的参数规模解析ChatGPT的参数体系 模型表现与局限性Kimi大模型的表现ChatGPT的表现 结论:如何选择适合自…...
详细解读CMA实验室认可
CMA实验室认可,即中国计量认证(China Metrology Accreditation)的实验室资质认定,以下是对其的详细解读: 一、定义与目的 CMA认证是经省级以上人民政府计量行政部门对实验室的计量检定、测试能力和可靠性考核合格后进…...
H5与支付宝小程序通信,调起扫一扫
1.public/index.html加入代码 <script>if (navigator.userAgent.indexOf(AliApp) > -1) {document.writeln(<script src"https://appx/web-view.min.js" > < / script>);}window.$my my </script>2.vue其他具体页面加入代码 metho…...
Lighthouse(灯塔)—— Chrome 浏览器性能测试工具
1.认识 Lighthouse Lighthouse 是 Google 开发的一款开源性能测试工具,用于分析网页或 Web 应用的性能、可访问性、最佳实践、安全性以及 SEO 等关键指标。开发人员可以通过 Lighthouse 快速了解网页的性能瓶颈,并基于优化建议进行改进。 核心功能&…...
深入浅出机器学习中的梯度下降算法
大家好,在机器学习中,梯度下降算法(Gradient Descent)是一个重要的概念。它是一种优化算法,用于最小化目标函数,通常是损失函数。梯度下降可以帮助找到一个模型最优的参数,使得模型的预测更加准…...
AIGC 012-Video LDM-更进一步,SD作者将LDM扩展到视频生成任务!
AIGC 012-Video LDM-Stable Video diffusion前身,将LDM扩展到视频生成任务! 文章目录 0 论文工作1论文方法实验结果 0 论文工作 Video LDM作者也是Stable diffusion的作者,作者在SD的架构上进行扩展,实现了视频的生成。后续在Vid…...
Rust常用命令总结
安装Rust 检查并更新Ubuntu的软件包 $ sudo apt update $ sudo apt upgrade安装相关依赖:安装GCC、G、MAKE、curl $ sudo apt install build-essential $ sudo apt install curl安装Rust $ curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh执行命令…...