微服务JWT的介绍与使用

1. 无状态登录

1.1 微服务的状态

​ 微服务集群中的每个服务,对外提供的都是Rest风格的接口,而Rest风格的一个最重要的规范就是:服务的无状态性。

​ 什么是无状态?

  1. 服务端不保存任何客户端请求者信息
  2. 客户端的每次请求必须具备自描述信息,通过这些信息识别客户端身份

​ 无状态,在微服务开放中,优势是?

  1. 客户端请求不依赖服务端的信息,任何多次请求不需要必须访问到同一台服务
  2. 服务端的是否集群对客户端透明
  3. 服务端可以任意的迁移和伸缩
  4. 减小服务端存储压力

1.2 无状态登录实现原理

在这里插入图片描述

服务器端生产唯一标识(注意:最终需要进行校验)

方案1:UUID,数据单一,不能包含种类过多的信息。

方案2:JWT 生成唯一标识,数据可以自定义。【使用】

为了保证JWT生成数据安全性,采用RSA加密。

浏览器存储和自动携带数据

方案1:使用cookie,有很多局限性(大小,个数)。

方案2:请求参数,get请求URL有长度限制,每一个路径都需要处理比较麻烦。

方案3:浏览器localStorage/sessionStorage存储,通过ajax的请求头携带。【使用】

在这里插入图片描述

1.3 RSA加密

1.3.1 概述

​ RSA公开密钥密码体制是一种使用不同的加密密钥与解密密钥,“由已知加密密钥推导出解密密钥在计算上是不可逆的”密码体制。

​ 在公开密钥密码体制中,加密密钥(即公开密钥)PK是公开信息,而解密密钥(即秘密密钥)SK是需要保密的。加密算法E和解密算法D也都是公开的。虽然解密密钥SK是由公开密钥PK决定的,但却不能根据PK计算出SK [2]。

​ RSA加密:非对称加密。

​ 同时生产一对秘钥:公钥和私钥。

​ 公钥秘钥:用于加密

​ 私钥秘钥:用于解密

​ 既然是加密,那肯定是不希望别人知道我的消息,所以只有我才能解密,所以可得出公钥负责加密,私钥负责解密;同理,既然是签名,那肯定是不希望有人冒充我发消息,只有我才能发布这个签名,所以可得出私钥负责签名,公钥负责验证。

使用RSA加密保证token数据在传输过程中不会被篡改。

1.3.2 工具类

package com.czxy.utils;import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
/*** Created by liangtong.*/
public class RsaUtils {/*** 从文件中读取公钥** @param filename 公钥保存路径,相对于classpath* @return 公钥对象* @throws Exception*/public static PublicKey getPublicKey(String filename) throws Exception {byte[] bytes = readFile(filename);return getPublicKey(bytes);}/*** 从文件中读取密钥** @param filename 私钥保存路径,相对于classpath* @return 私钥对象* @throws Exception*/public static PrivateKey getPrivateKey(String filename) throws Exception {byte[] bytes = readFile(filename);return getPrivateKey(bytes);}/*** 获取公钥** @param bytes 公钥的字节形式* @return* @throws Exception*/public static PublicKey getPublicKey(byte[] bytes) throws Exception {X509EncodedKeySpec spec = new X509EncodedKeySpec(bytes);KeyFactory factory = KeyFactory.getInstance("RSA");return factory.generatePublic(spec);}/*** 获取密钥** @param bytes 私钥的字节形式* @return* @throws Exception*/public static PrivateKey getPrivateKey(byte[] bytes) throws Exception {PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);KeyFactory factory = KeyFactory.getInstance("RSA");return factory.generatePrivate(spec);}/*** 根据密文,生存rsa公钥和私钥,并写入指定文件** @param publicKeyFilename  公钥文件路径* @param privateKeyFilename 私钥文件路径* @param secret             生成密钥的密文* @throws Exception*/public static void generateKey(String publicKeyFilename, String privateKeyFilename, String secret) throws Exception {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");SecureRandom secureRandom = new SecureRandom(secret.getBytes());keyPairGenerator.initialize(1024, secureRandom);KeyPair keyPair = keyPairGenerator.genKeyPair();// 获取公钥并写出byte[] publicKeyBytes = keyPair.getPublic().getEncoded();writeFile(publicKeyFilename, publicKeyBytes);// 获取私钥并写出byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();writeFile(privateKeyFilename, privateKeyBytes);}private static byte[] readFile(String fileName) throws Exception {return Files.readAllBytes(new File(fileName).toPath());}private static void writeFile(String destPath, byte[] bytes) throws IOException {File dest = new File(destPath);//创建父文件夹if(!dest.getParentFile().exists()){dest.getParentFile().mkdirs();}//创建需要的文件if (!dest.exists()) {dest.createNewFile();}Files.write(dest.toPath(), bytes);}
}

1.3.3 生产公钥和私钥

package com.czxy.utils;import org.junit.Test;import java.security.PrivateKey;
import java.security.PublicKey;/*** Created by liangtong.*/
public class TestRsa {private static final String pubKeyPath = "D:\\rsa\\rsa.pub";private static final String priKeyPath = "D:\\rsa\\rsa.pri";@Testpublic void testRas() throws Exception {//生产公钥和私钥RsaUtils.generateKey(pubKeyPath, priKeyPath, "234");}@Testpublic void testGetRas() throws Exception {//获得公钥和私钥PublicKey publicKey = RasUtils.getPublicKey(pubKeyPath);PrivateKey privateKey = RasUtils.getPrivateKey(priKeyPath);System.out.println(publicKey.toString());System.out.println(privateKey.toString());}

1.4 JWT

1.4.1 概述

​ JWT,全称是Json Web Token, 是JSON风格轻量级的授权和身份认证规范,可实现无状态、分布式的Web应用授权;官网:https://jwt.io

1.4.2 添加坐标

<properties><jwt.jjwt.version>0.9.0</jwt.jjwt.version><jwt.joda.version>2.9.7</jwt.joda.version><lombok.version>1.16.20</lombok.version><beanutils.version>1.9.3</beanutils.version>
</properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>${beanutils.version}</version></dependency><dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt</artifactId><version>${jwt.jjwt.version}</version></dependency><dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>${jwt.joda.version}</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>${lombok.version}</version><scope>provided</scope></dependency></dependencies>

1.4.3 时间处理工具:DateTime

//当前时间
DateTime.now().toDate().toLocaleString()
//当前时间加5分钟
DateTime.now().plusMinutes(5).toDate().toLocaleString()
//当前时间减5分钟
DateTime.now().minusMinutes(5).toDate().toLocaleString()

1.4.4 测试JWT

生成Token
@Test
public void testGenerateToken() throws Exception {String str = Jwts.builder().claim("test","测试数据").setExpiration(DateTime.now().plusMinutes(60).toDate()).signWith(SignatureAlgorithm.RS256,RsaUtils.getPrivateKey(priKeyPath)).compact();System.out.println(str);
}
解析Token
@Test
public void testParseToken() throws Exception {String token = "";Claims claims = Jwts.parser().setSigningKey(RsaUtils.getPublicKey(pubKeyPath)).parseClaimsJws(token).getBody();String text = claims.get("test",String.class);System.out.println(text);
}

1.4.5 工具类:JwtUtils

package com.czxy.utils;import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.apache.commons.beanutils.BeanUtils;
import org.joda.time.DateTime;import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.security.PrivateKey;
import java.security.PublicKey;/*** Created by liangtong.*/
public class JwtUtils {/***  私钥加密token* @param data 需要加密的数据(载荷内容)* @param expireMinutes 过期时间,单位:分钟* @param privateKey 私钥* @return*/public static String generateToken(Object data, int expireMinutes, PrivateKey privateKey) throws Exception {//1 获得jwt构建对象JwtBuilder jwtBuilder = Jwts.builder();//2 设置数据if( data == null ) {throw new RuntimeException("数据不能为空");}BeanInfo beanInfo = Introspector.getBeanInfo(data.getClass());PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {// 获得属性名String name = propertyDescriptor.getName();// 获得属性值Object value = propertyDescriptor.getReadMethod().invoke(data);if(value != null) {jwtBuilder.claim(name,value);}}//3 设置过期时间jwtBuilder.setExpiration(DateTime.now().plusMinutes(expireMinutes).toDate());//4 设置加密jwtBuilder.signWith(SignatureAlgorithm.RS256, privateKey);//5 构建return jwtBuilder.compact();}/*** 通过公钥解析token* @param token 需要解析的数据* @param publicKey 公钥* @param beanClass 封装的JavaBean* @return* @throws Exception*/public static <T> T  getObjectFromToken(String token, PublicKey publicKey,Class<T> beanClass) throws Exception {//1 获得解析后内容Claims body = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token).getBody();//2 将内容封装到对象JavaBeanT bean = beanClass.newInstance();BeanInfo beanInfo = Introspector.getBeanInfo(beanClass);PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {// 获得属性名String name = propertyDescriptor.getName();// 通过属性名,获得对应解析的数据Object value = body.get(name);if(value != null) {// 将获得的数据封装到对应的JavaBean中BeanUtils.setProperty(bean,name,value);}}return bean;}
}

1.4.6 生产token和校验token

编写测试对象UserInfo
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserInfo {private Long id;private String username;
}
编写测试类
package com.czxy.utils;import com.czxy.entity.UserInfo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.joda.time.DateTime;
import org.junit.Test;/*** Created by liangtong.*/
public class TestJWT {private static final String pubKeyPath = "D:\\rsa\\rsa.pub";private static final String priKeyPath = "D:\\rsa\\rsa.pri";@Testpublic void testToken() throws Exception {UserInfo userInfo = new UserInfo();userInfo.setId(10L);userInfo.setUsername("用户名");String token = JwtUtils.generateToken(userInfo, 30, RsaUtils.getPrivateKey(priKeyPath));System.out.println(token);}@Testpublic void testParserToken() throws Exception {String token = "eyJhbGciOiJSUzI1NiJ9.eyJjbGFzcyI6ImNvbS5jenh5LmVudGl0eS5Vc2VySW5mbyIsImlkIjoxMCwidXNlcm5hbWUiOiLnlKjmiLflkI0iLCJleHAiOjE1NzU5MTYyMDl9.W3Q3Iz1vGq1nf7RQW3eAzkMvkME9P5_5zoDcFQXX0eke07lA2PLuZGCYcB6-DI0i7UrahFOmB0OFQodrK_3CZkrh-sI_802twkGatRaI0ifetRLV_1XHVl_Lymh6SaDdBB1OT3-EQCAppjoHFb9Tyq1EGyQZ5xoU-vLp7fzNQLQ";UserInfo userInfo = JwtUtils.getObjectFromToken(token, RsaUtils.getPublicKey(pubKeyPath), UserInfo.class);System.out.println(userInfo);}
}

1.4.7 扩展:JWT token组成

JWT的token包含三部分数据:头部、载荷、签名。

名称描述组成部分
头部(Header)通常头部有两部分信息1. 声明类型,这里是JW2. 加密算法,自定义
载荷(Payload)就是有效数据1. 用户身份信息2. 注册声明
签名(Signature)整个数据的认证信息一般根据前两步的数据,再加上服务的的密钥(secret),通过加密算法生成。用于验证整个数据完整和可靠性
生成的数据格式:

在这里插入图片描述

1.5 Zuul整合JWT

1.5.1 自定义配置内容

修改application.yml 添加内容
#自定义内容
sc:jwt:secret: sc@Login(Auth}*^31)&czxy% # 登录校验的密钥(自定义内容)pubKeyPath: D:/rsa/rsa.pub # 公钥地址priKeyPath: D:/rsa/rsa.pri # 私钥地址expire: 360 # 过期时间,单位分钟filter:allowPaths:- /checkusername- /checkmobile- /sms- /register- /login- /verifycode- /categorys- /news- /brands- /sku/esData- /specifications- /search- /goods- /comments- /pay/callback

1.5.2 JWT配置类

package com.czxy.changgou3.config;import com.czxy.utils.RasUtils;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.io.File;
import java.security.PrivateKey;
import java.security.PublicKey;/*** Created by liangtong.*/
@Data
@ConfigurationProperties(prefix = "sc.jwt")
@Component
public class JwtProperties {private String secret; // 密钥private String pubKeyPath;// 公钥private String priKeyPath;// 私钥private int expire;// token过期时间private PublicKey publicKey; // 公钥private PrivateKey privateKey; // 私钥private static final Logger logger = LoggerFactory.getLogger(JwtProperties.class);@PostConstructpublic void init(){try {File pubFile = new File(this.pubKeyPath);File priFile = new File(this.priKeyPath);if( !pubFile.exists() || !priFile.exists()){RasUtils.generateKey( this.pubKeyPath ,this.priKeyPath , this.secret);}this.publicKey = RasUtils.getPublicKey( this.pubKeyPath );this.privateKey = RasUtils.getPrivateKey( this.priKeyPath );} catch (Exception e) {e.printStackTrace();}}}

1.5.3 过滤路径配置类

package com.czxy.changgou3.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;import java.util.List;/*** Created by liangtong.*/
@Data
@ConfigurationProperties(prefix="sc.filter")
public class FilterProperties {//允许访问路径集合private List<String> allowPaths;
}

1.5.4 过滤器

package com.czxy.changgou3.filter;import com.czxy.changgou3.config.FilterProperties;
import com.czxy.changgou3.config.JwtProperties;
import com.czxy.changgou3.pojo.User;
import com.czxy.utils.JwtUtils;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.netflix.zuul.filters.support.FilterConstants;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;/*** Created by liangtong.*/
@Component
//2.1 加载JWT配置类
@EnableConfigurationProperties({JwtProperties.class , FilterProperties.class} )
public class LoginFilter  extends ZuulFilter {//2.2 注入jwt配置类实例@Resourceprivate JwtProperties jwtProperties;@Resourceprivate FilterProperties filterProperties;@Overridepublic String filterType() {return FilterConstants.PRE_TYPE;}@Overridepublic int filterOrder() {return 5;}@Overridepublic boolean shouldFilter() {     //03.当前过滤器是否执行,true执行,false不执行//3.1 获得用户请求路径// 3.1.1 获得上下文RequestContext currentContext = RequestContext.getCurrentContext();// 3.1.2 获得requestHttpServletRequest request = currentContext.getRequest();// 3.1.2 获得请求路径  , /v3/cgwebservice/loginString requestURI = request.getRequestURI();//3.2 如果路径是 /auth-service/login ,当前拦截不执行for (String path  : filterProperties.getAllowPaths()) {//判断结尾if(requestURI.contains(path)){return false;}}//3.3 其他都执行 run()方法return true;}@Overridepublic Object run() throws ZuulException {//1 获得token//1.1 获得上下文RequestContext currentContext = RequestContext.getCurrentContext();//1.2 获得request对象HttpServletRequest request = currentContext.getRequest();//1.3 获得指定请求头的值String token = request.getHeader("Authorization");//2 校验token -- 使用JWT工具类进行解析// 2.3 使用工具类,通过公钥获得对应信息try {JwtUtils.getObjectFromToken(token , jwtProperties.getPublicKey() , User.class);} catch (Exception e) {// 2.4 如果有异常--没有登录(没有权限)currentContext.addOriginResponseHeader("content-type","text/html;charset=UTF-8");currentContext.addZuulResponseHeader("content-type","text/html;charset=UTF-8");currentContext.setResponseStatusCode( 403 );        //响应的状态码:403currentContext.setResponseBody("token失效或无效");currentContext.setSendZuulResponse( false );        //没有响应内容}// 2.5 如果没有异常,登录了--放行return null;}
}

1.6 下游服务获得token

在这里插入图片描述

zuul默认配置
zuul:sensitive-headers: Cookie,Set-Cookie,Authorization

在这里插入图片描述

修改zuul配置,及删除配置

在这里插入图片描述

其他服务中,可以通过request获得内容

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数据结构—基础知识(13):树的存储结构

数据结构—基础知识&#xff08;13&#xff09;&#xff1a;树的存储结构 双亲表示法 这种表示方法中&#xff0c;以一组连续的存储单元存储树的结点&#xff0c;每个结点除了数据域data外&#xff0c;还附设一个parent域用以指示其双亲结点的位置。 这种存储结构利用了每个结…

手搓反向迭代器

前言 关于反向迭代器&#xff0c;字如其名&#xff0c;就是将正向迭代器&#xff0c;从反方向再迭代一次就成了&#xff0c;所以我们如此设计反向迭代器&#xff1a; 假设我们已经拥有了一套能够使用&#xff0c;且包含模板的正向迭代器利用适配器模式&#xff0c;让反向迭代…

软件测试生命周期

本章简要介绍了软件开发项目中常用的生命周期模型&#xff0c;并解释了测试在每个模型中扮演的角色。它讨论了各种测试级别和测试类型之间的区别&#xff0c;并解释了这些在开发过程中的应用位置和方式。 大多数软件开发项目是按照事先选择的软件开发生命周期模型来计划和执行…

ZK监控方法以及核心指标

文章目录 1. 监控指标采集1.1 zk版本高于3.6.0监控指标采集1.2 zk版本低于3.6.0监控指标采集1.3 配置promethues采集和大盘 2. 核心告警指标3. 参考文章 探讨zk的监控数据采集方式以及需要关注的核心指标&#xff0c;便于日常生产进行监控和巡检。 1. 监控指标采集 3.6.0 版本…

ORA-12528: TNS: 监听程序: 所有适用例程都无法建立新连

用了网上的办法&#xff1a; 1、修改listener.ora的参数,把动态的参数设置为静态的参数,红色标注部分 位置D:\oracle\product\10.2.0\db_1\NETWORK\ADMIN SID_LIST_LISTENER (SID_LIST (SID_DESC (SID_NAME PLSExtProc) (ORACLE_HOME D:\oracle\produ…

基于PHP反序列化练习

PHP创建一个以自己姓名命名的类&#xff0c;要求存在两个属性&#xff0c;name&#xff0c;age&#xff0c;进行序列化&#xff0c;输出序列化以后的数据。 <!-- PHP创建一个以自己姓名命名的类&#xff0c;要求存在两个属性&#xff0c;name&#xff0c;age --> <?…

【C/C++】C/C++编程——第一个 C++ 程序:HelloWorld

第一个 C 程序&#xff1a;HelloWorld 大家好&#xff0c;我是 shopeeai&#xff0c;也可以叫我虾皮&#xff0c;中科大菜鸟研究生。昨天我们成功搭建好了 C 的开发环境&#xff0c;今天我们来介绍一下第一个 C 程序,打印一个"hello world"。首先我们先贴一下示例代…

【FPGA Verilog开发实战指南】初识Verilog HDL-基础语法

这里写目录标题 Verilog HDL简介与VHDL比较 Verilog HDL基础语法逻辑值关键字moduleendmodule 模块名输入信号输出信号既做输入也做输出线网型变量 wire寄存器型变量 reg参数 parameter参数 localparam常量赋值方式阻塞赋值非阻塞赋值 always语句assign 语句 算数运算符归元运算…

C++ Qt day2

自己封装一个矩形类(Rect)&#xff0c;拥有私有属性:宽度(width)、高度(height)&#xff0c; 定义公有成员函数: 初始化函数:void init(int w, int h) 更改宽度的函数:set_w(int w) 更改高度的函数:set_h(int h) 输出该矩形的周长和面积函数:void show() #include <io…

翻译: 使用 GPT-4 将您的 Streamlit 应用程序提升到一个新的水平一

帮助您更快地设计、调试和优化 Streamlit 应用的专业技巧 设计和扩展 Streamlit 应用程序可能是一项艰巨的任务&#xff01;作为开发人员&#xff0c;我们经常面临一些挑战&#xff0c;例如设计良好的 UI、快速调试我们的应用程序以及快速制作它们。 如果有一个工具可以加快速…

Tomcat运维

目录 一、Tomcat简介 二、系统环境说明 1、关闭防火墙&#xff0c;selinux 2、安装JDK 3、安装Tomcat 三、Tomcat目录介绍 1、tomcat主目录介绍 2、webapps目录介绍 3、Tomcat配置介绍&#xff08;conf&#xff09; 4、Tomcat的管理 四、Tomcat 配置管理页面(了解) …

类和对象 第三部分第三小节:const修饰成员函数

一.常函数&#xff1a; &#xff08;一&#xff09;成员函数后面加const后我们成这个函数为常函数 &#xff08;二&#xff09;常函数内不可以修改成员函数属性 额外补充&#xff1a; this指针的本质&#xff0c;是指针常量&#xff0c;指针指向的是不可以修改的 但是指针指向的…

响应式Web开发项目教程(HTML5+CSS3+Bootstrap)第2版 例4-11 HTML5 表单验证

代码 <!doctype html> <html> <head> <meta charset"utf-8"> <title>HTML5 表单验证</title> </head><body> <form action"#" method"get" novalidate>请输入您的邮箱:<input type&q…

无限学模式-“科研创新的加速器:全面掌握ChatGPT,推动研究方法和工作模式现代化!“

2023年随着OpenAI开发者大会的召开&#xff0c;最重磅更新当属GPTs&#xff0c;多模态API&#xff0c;未来自定义专属的GPT。微软创始人比尔盖茨称ChatGPT的出现有着重大历史意义&#xff0c;不亚于互联网和个人电脑的问世。360创始人周鸿祎认为未来各行各业如果不能搭上这班车…

小型商用机器人,如何做到小而强?

兼顾体型和性能。 体型和性能的矛盾 一直以来&#xff0c;商用清洁机器人的应用场景主要集中在大型商场、超市、写字楼等&#xff0c;为什么1000平米以下的小型商超等中小场景却很少涉足&#xff1f;原因可以说有很多&#xff0c;但核心为两方面&#xff0c;一方面&#xff0…

YOLOv8优化策略:注意力涨点系列篇 | 一种轻量级的加强通道信息和空间信息提取能力的MLCA注意力

🚀🚀🚀本文改进:一种轻量级的加强通道信息和空间信息提取能力 MLCA注意力 🚀🚀🚀在YOLOv8中如何使用 1)作为注意力机制使用;2)与c2f结合使用; 🚀🚀🚀YOLOv8改进专栏:http://t.csdnimg.cn/hGhVK 学姐带你学习YOLOv8,从入门到创新,轻轻松松搞定科研…

PaddleOCR将自己训练的模型转换为openvino格式模型

1 训练模型 python train_steelseal_det.py2 checkpoints模型转换为inference 模型 加载配置文件ch_PP-OCRv4_det_student_steelseal.yml&#xff0c;从./output/ch_PP-OCRv4/best_model/目录下加载model模型&#xff0c;inference模型保存在./output/ch_PP-OCRv4/best_model…

机器学习 | 深入探索Numpy的高性能计算能力

目录 初识numpy numpy基本操作 数组的基本操作 ndarray运算 数组间运算 矩阵 初识numpy Numpy&#xff08;Numerical Python&#xff09;是一个开源的Python科学计算库&#xff0c;用于快速处理任意维度的数组。Numpy支持常见的数组和矩阵操作。对于同样的数值计算任务&…

视频尺寸魔方:分层遮掩3D扩散模型在视频尺寸延展的应用

▐ 摘要 视频延展(Video Outpainting)是对视频的边界进行扩展的任务。与图像延展不同&#xff0c;视频延展需要考虑到填充区域的时序一致性&#xff0c;这使得问题更具挑战性。在本文中&#xff0c;我们介绍了一个新颖的基于扩散模型的视频尺寸延展方法——分层遮掩3D扩散模型(…

盛况空前 火热来袭 ▏2024上海国际轴承及其专用装备展览会暑期归来

中国设备管理协会主办的“2024上海国际轴承及其专用装备展览会”将于2024年7月24日至26日在“国家会展中心&#xff08;虹桥&#xff09;”举办。展会预计展出面积55000平方米&#xff0c;汇聚来自世界各地的近1000家企业与60000多人次的国内外观众齐聚一堂。为期三天的展览会是…