springboot实战学习(7)(JWT令牌的组成、JWT令牌的使用与验证)
接着上篇博客的学习。上篇博客是在基本完成用户模块的注册接口的开发以及注册时的参数合法性校验的基础上,基本完成用户模块的登录接口的主逻辑以及提到了问题:"用户未登录,需要通过登录,获取到令牌进行登录认证,才能使用其他功能的接口"。具体往回看了解的链接如下。springboot实战学习(6)(用户模块的登录认证)(初识令牌)(JWT)-CSDN博客文章浏览阅读2次。本篇博客是在处理用户模块中登录认证时遇到需要解决的问题。因为未登录时,需要做到无法访问和使用其他功能的接口。也就提到了令牌的作用以及满足令牌的规范"JWT"。具体的学习下篇博客进行学习...
https://blog.csdn.net/m0_74363339/article/details/142365524?spm=1001.2014.3001.5502
接下来就去认真了解和学习Web登录认证中常用的令牌规范——>"JWT"。
目录
一、JWT(令牌规范)
(1)基本介绍
(2)基本组成
(I)解释上方图片(JWT令牌字符串)
(II)总结组成
二、程序中使用JWT令牌
(1)回顾与思考
三、JWT令牌的生成
(1)JWT令牌示范
(1)如何生成
(2)如何使用生成"JWT令牌"工具
(I)第一步。导入工具的坐标(依赖)
(II)第二步。调用API,生成令牌。
(III)生成"JWT令牌"的代码不需要去记忆
(3)IDEA中写单元测试的方法测试生成JWT令牌
四、JWT令牌的验证
(1)DEA中写单元测试的方法测试"JWT令牌"的验证
(2)测试因篡改"JWT令牌"导致验证失败的几种情况
(I)篡改JWP令牌"头部部分"进行验证。
编辑
(II)篡改JWP令牌中间"载荷部分"进行验证。
(III)篡改JWP令牌尾部"数字签名"(篡改密钥)进行验证。
(3)处理因篡改JWT令牌的数据导致的异常
(I)如果篡改了头部和载荷部分的数据,那么验证失败。
(II)如果篡改了密钥数据,那么验证失败。
(III)如果超过设定的Token令牌过期时间,那么验证失败。
(4)关于"JWT令牌"验证的注意事项
五、总结
(1)JWT令牌的组成
(2)JWT令牌的使用
(3)尾言
一、JWT(令牌规范)
(1)基本介绍
JSON Web Tokens - jwt.ioJSON Web Token (JWT) is a compact URL-safe means of representing claims to be transferred between two parties. The claims in a JWT are encoded as a JSON object that is digitally signed using JSON Web Signature (JWS).
- JWT的全称:JSON Web Token
https://jwt.io/
(也就是用于Web领域的基于JSON格式的令牌)
- 定义了一种简洁的、自包含的格式,用于通信双方以json数据格式安全的传输信息。
(JSON是一种文本数据格式,来源于JavaScript的对象语法。)
(2)基本组成
(I)解释上方图片(JWT令牌字符串)
- 上面展示的它是前后端交互时传输的字符串。而这个字符串是由JSON格式的字符串编码得来的字符串。可以看到上面字符串有两个小".",它就是把这整个字符串分为三个部分。而"分割"的每一个小串,对应着Token令牌的一部分。
- 第一部分是头。它是由JSON字符串编码得来的。这个部分的字符串会记录两个信息。第一个是"alg"(它是加密算法,防篡改),而"type"(是JWT)。
- 第二部分是"有效载荷"。它是也是一段字符串。而在这段字符串中,他会存放我们的业务数据。比如存放用户的id、用户的username等等。这段字符串编码后,也会得到上面Token令牌里面的这一段。
- 而对应的JSON格式的字符串,是如何转换为上面Token令牌中展示的这一段"特殊长的字符串"呢?在JWT中会借助于"base64"这种编码方式完成。而"base64"可以将任意数据转换成64个可打印字符('a'-'z'、'A'-'Z'、'0'-'9'等等)。这些64个可打印字符最重要的特点就是:"通用",在任意场景都可以被支持。
- 将JSON格式的字符串转换为64个可打印的字符串,原因是为了提供Token令牌的实用性。记得"base64"仅仅是一种编码方式,而不是加密。因此记得在Token令牌的第二部分"有效载荷",一定注意不要放私密数据(比如用户密码等),不然不安全。
- 最后一部分叫做"数字签名"。它是将第一部分以及第二部分,借助于密钥和加密算法,通过加密得来的。而这里的加密算法,是通过头部的"alg"来制定的。密钥可以在程序中单独配置。
- 有了这个数字签名,就可以防篡改,确保Token是安全的。因为将来即使篡改了第一和第二部分,但第三部分是不能篡改的,因为是加密后的字符串。将来JWT再去解析Token令牌时,通过解密第三部分,得到"头部"与"载荷",再拿到解密的内容与用户传递的内容进行比对,如果不一样,就不让访问。
(II)总结组成
二、程序中使用JWT令牌
(1)回顾与思考
- 回到之前的所完成用户模块的注册接口与登录接口的主逻辑。
springboot实战学习笔记(5)(用户登录接口的主逻辑)-CSDN博客
- 现在需要在用户登录之后生成一个"JWT令牌",生成了之后还需要把"JWT令牌"响应给浏览器。
- 将来浏览器再去访问服务器上的其它资料时,会携带这个令牌访问。这时服务器就能够得到这个令牌,并且还需要去验证这个令牌的合法性。如果令牌合法、没有被篡改,就正常提供服务,反之。
- 需要学习如何生成令牌?如何验证令牌?
三、JWT令牌的生成
(1)JWT令牌示范
(1)如何生成
- 可以自己手写,毕竟JWT是一个令牌的规范写法。而是规范,大家都可以实现的。
- 有人提供了生成"JWT令牌"的工具,所以可以直接使用这些工具即可。
(2)如何使用生成"JWT令牌"工具
(I)第一步。导入工具的坐标(依赖)
引入的是java-jwt
引入坐标时,报错,记得尝试刷新一个Maven
因为我们当前写的"生成令牌"或者"验证令牌"代码,它仅仅是一个测试的代码。所以需要把它写到单元测试里面。所以还要引入单元测试的坐标
springboot为了更方便的测试spring程序,提供了springboot整合单元测试的一个起步依赖。
添加完毕,一定记得刷新Maven。
(II)第二步。调用API,生成令牌。
(III)生成"JWT令牌"的代码不需要去记忆
- 因为将来在公司中使用的时候,都是使用提供好的工具类,然后直接调用即可
(3)IDEA中写单元测试的方法测试生成JWT令牌
- 在test目录的feisi目录下,新建一个类"JwtTest"。在这个类的内部去写单元测试的代码。
- 新建一个方法testGen(),并且需要在方法上添加一个注解@Test。
- 如果要生成令牌,就要调用JWT的API。然后先调用其create()方法。
- 然后利用链式编程的方式来调用方法。首先调用第一个方法"withClaim()",这个方法的作用是添加"载荷"(前面讲过)。
- 这个添加载荷的方法就是:第一值传入键的名字(name)(如这里设置为"user",那么将来这个载荷就是承载着用户相关的信息),第二个参数值放一个map集合,比如user将来肯定有"id"、"username"等等。
JWT.create().withClaim("user",claims);
- 所以接着就要创建一个Map类型的集合。指定其键是"String"类型,而值是"Object"类型的。
Map<String, Object> claims = new HashMap<>();
- 有了这个claims集合,就可以调用方法put()。如下添加。这样就提供添加"载荷"的方式,把当前用户信息添加进去了。
claims.put("id",1);claims.put("username","张三");
- 接下来JWT.create().后面还可以添加几个方法。
- 如.withExpiresAt()。这是添加过期时间。也就是登录时获得的令牌是有登录有效期的,时间过了,就需要重新登录。将来的Token令牌是有有效期的。
- 里面是需要一个Data对象。直接new Data()。但是这个是当前的时间,所以还需要通过System提供的获取当前毫秒值的方法,再重新new一个Data对象。往后延迟指定一段时间。
- 当前毫秒值+1000*60*60*12(也就是延后12个小时)。
JWT.create().withClaim("user",claims).withExpiresAt(new Date(System.currentTimeMillis()+1000*60*60*12));
- 如sign()方法。"sign"是签名的意思。也就是如上面说的数字签名,加密用的。方法参数需要指定一个加密算法。这里选择HMAC256()这个算法。
- 在指定算法的时候,需要指定一个密钥。这个是由自己定就行,就是一个字符串。但是它是加密的密钥,所以不要泄露,不然不能防篡改,保证安全。
.sign(Algorithm.HMAC256("feisi"));//指定算法,配置密钥
- 这几个方法一旦调用,我们的Token令牌就能生成。所以就要去接收一下Token。
package com.feisi;import com.auth0.jwt.JWT; import com.auth0.jwt.algorithms.Algorithm; import org.junit.jupiter.api.Test;import java.util.Date; import java.util.HashMap; import java.util.Map;public class JwtTest {//生成JWT令牌的方法@Testpublic void testGen(){Map<String, Object> claims = new HashMap<>();claims.put("id",1);claims.put("username","张三");//生成JWT代码String token = JWT.create().withClaim("user",claims) //添加载荷.withExpiresAt(new Date(System.currentTimeMillis()+1000*60*60*12)) //添加过期时间.sign(Algorithm.HMAC256("feisi"));//指定算法,配置密钥//打印输出到控制台,查看生成的token令牌System.out.println(token);} }
- 最后运行一下这个测试类的方法。这样"JWT令牌"的生成就完成了。
四、JWT令牌的验证
(1)DEA中写单元测试的方法测试"JWT令牌"的验证
- 首先这一部分的代码也不需要去背或者记忆。
- 接着上面,在"testGen()"方法下添加一个方法"testParse()"。
- 也是一样记得添加单元测试的注解@Test。
- 接着定义一个字符串"token",模拟存储用户传递给浏览器的token令牌。
- 而这个token的值就用上面控制台打印的token令牌字符串就行。
//验证JWT令牌的方法@Testpublic void testParse(){//定义字符串,模拟用户传递给浏览器的token令牌//这个token就用上面生成的token令牌字符串就行String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"+".eyJ1c2VyIjp7ImlkIjoxLCJ1c2VybmFtZSI6IuW8oOS4iSJ9LCJleHAiOjE3MjcwMzg2MDl9"+".LgfVNY-OAkjAps8yQXDkKyCIRbWw5jNQiNZwwbMf2F4";}
- 接着开始提供验证了。去提供调用JWT这个类里面的一个静态方法"require()"。这是申请一个JWT的验证器。
- 而这个方法里面的参数需要传递一个算法。之前加密用的算法,解密也要同样用一样的算法。直接复制过来。
- 然后再调用一个".build()"方法去生成验证器。再用一个变量"jwtVerifier"给他存起来。
JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("feisi")).build();
- 有了这个变量之后,就可以调用验证器的方法,去验证这个token令牌字符串。
- 调用方法".verify()",把之前控制台的token传递给它。
- 它可以去解析这个token令牌。然后生成一个解析后的JWT对象。
DecodedJWT decodedJWT = jwtVerifier.verify(token); //验证token,生成一个解析后的JWT对象
- 如果能正常的解析成功之后。那么就意味着可以从变量"decodedJWT"里面获取到当前的"头部"或者"载荷"以及"数字签名"等等。
- 则调用它的一个方法:"GetClaims()",而它会得到所有的"载荷"。用Map对象的变量去接收一下它。
Map<String, Claim> claims = decodedJWT.getClaims();
- 然后我们指定获取键名(name)为"user"的载荷。并且把得到的结果输出到控制台里面。
package com.feisi;import com.auth0.jwt.JWT; import com.auth0.jwt.JWTVerifier; import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.interfaces.Claim; import com.auth0.jwt.interfaces.DecodedJWT; import org.junit.jupiter.api.Test;import java.util.Date; import java.util.HashMap; import java.util.Map;public class JwtTest {//生成JWT令牌的方法@Testpublic void testGen(){Map<String, Object> claims = new HashMap<>();claims.put("id",1);claims.put("username","张三");//生成JWT代码String token = JWT.create().withClaim("user",claims) //添加载荷.withExpiresAt(new Date(System.currentTimeMillis()+1000*60*60*12)) //添加过期时间.sign(Algorithm.HMAC256("feisi"));//指定算法,配置密钥//打印输出到控制台,查看生成的token令牌System.out.println(token);}//验证JWT令牌的方法@Testpublic void testParse(){//定义字符串,模拟用户传递给浏览器的token令牌//这个token就用上面生成的token令牌字符串就行String token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9"+".eyJ1c2VyIjp7ImlkIjoxLCJ1c2VybmFtZSI6IuW8oOS4iSJ9LCJleHAiOjE3MjcwMzg2MDl9"+".LgfVNY-OAkjAps8yQXDkKyCIRbWw5jNQiNZwwbMf2F4";JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256("feisi")).build();DecodedJWT decodedJWT = jwtVerifier.verify(token); //验证token,生成一个解析后的JWT对象Map<String, Claim> claims = decodedJWT.getClaims();System.out.println(claims.get("user"));} }
- 得到控制台的正常输出,如:"id,1"、"username,"张三""等等就解析成功了!
- 正常的解析成功如下。
(2)测试因篡改"JWT令牌"导致验证失败的几种情况
(I)篡改JWP令牌"头部部分"进行验证。
(II)篡改JWP令牌中间"载荷部分"进行验证。
所以我们的JWT令牌是具体放篡改的功能的。
(III)篡改JWP令牌尾部"数字签名"(篡改密钥)进行验证。
- 篡改了原来设定的密钥"feisi"改成"fesi"。
(3)处理因篡改JWT令牌的数据导致的异常
(I)如果篡改了头部和载荷部分的数据,那么验证失败。
(II)如果篡改了密钥数据,那么验证失败。
(III)如果超过设定的Token令牌过期时间,那么验证失败。
(Token过期)
- 例如如下情况:报错提示"这个Token令牌"已经过期。
(4)关于"JWT令牌"验证的注意事项
五、总结
(1)JWT令牌的组成
- "载荷"这一块要注意。不要存放一些私密信息,因为"base64"算法不是一个加密算法,它是公开的,每个人都能使用
- 通过密钥与加密算法去验证Token令牌的合法性
(2)JWT令牌的使用
(借助工具:"JAVA-JWT")
(3)尾言
下篇博客就要开始继续完成用户登录认证的接口开发了!也就是把令牌的生成与验证加入到登录功能中。
相关文章:
springboot实战学习(7)(JWT令牌的组成、JWT令牌的使用与验证)
接着上篇博客的学习。上篇博客是在基本完成用户模块的注册接口的开发以及注册时的参数合法性校验的基础上,基本完成用户模块的登录接口的主逻辑以及提到了问题:"用户未登录,需要通过登录,获取到令牌进行登录认证,…...
如何使用numpy反转数组
如何使用numpy反转数组 1、使用np.flip()函数 可以使用flip(m, axisNone)函数来对数组进行反转: m:输入数组 axis:为None则行列都反转 axis:为0则反转行 axis:为1则反转列2、代码 import numpy as np# 创建一维数组 arr np.array([[1, 2, 3, 4, 5],[2, 2, 3, 4…...
Linux·进程概念(上)
1.操作系统 任何计算机系统都包含一个基本的程序合集,称为操作系统(Operator System)。笼统的理解,操作系统包括: 内核(进程管理,内存管理,文件管理,驱动管理) 其他程序(函数库,shell程序) OS的…...
Javax Validation 自定义注解校验(身份证号校验)
一、场景分析 我们使用 SpringMVC 在 Controller 层,对身份证号进行数据校验的话,经常采用以下方式: RestController RequiredArgsConstructor RequestMapping("member") public class MemberController {// 身份证号码正则表达式…...
nid修改orac库和实例名为jyc
由于库太大,并且要求修改源库的实例名,所以考虑采用nid方式重建控制文件,实现名称和路径的完美替换。 oracleJYCDB:/home/oracle/scripts> oracleJYCDB:/home/oracle/scripts>echo $ORACLE_SID orac oracleJYCDB:/home/oracle/scripts…...
无人机之模拟图传篇
无人机的模拟图传技术是一种通过模拟信号传输图像数据的方式,它通常使用无线电模块或专用通信协议进行数据传输。 一、基本原理 模拟图传技术的工作原理是将摄像头或相机设备采集到的图像数据,通过模拟信号的形式进行传输。这些模拟信号在传输过程中可能…...
Ubuntu 20.04安装pycharm2022及配置快捷方式
一、下载与安装 1. 下载 在 官网 下载所需版本,如:下载 2022.3.3 - Linux (tar.gz) 2. 安装 设置自定义安装路径(推荐在 /opt/ 路径下)并安装 mkdir -p ~/Documents/software/pycharm/ cd ~/Documents/software/pycharm/ mv ~/Downloads/pycharm-c…...
uni-app - - - - - 实现锚点定位和滚动监听功能(滚动监听功能暂未添加,待后续更新)
实现锚点定位和滚动监听功能 1. 思路解析2. 代码示例 效果截图示例: 点击左侧menu,右侧列表数据实现锚点定位 1. 思路解析 点击左侧按钮,更新右侧scroll-view对应的scroll-into-view的值,即可实现右侧锚点定位滚动右侧区域&am…...
wordpress迁移到别的服务器
wordpress论坛网站搭建 于2023/11/16写的该文章 一-配置环境 配置LNMP(linuxnginxmysqlphpphpmyadmin)环境或者LAMP(apache) 可以选择集成了这些软件的套件 下载链接:https://www.xp.cn/download.html 手动下载这…...
cefsharp新版本OnBeforeResourceLoad 禁止http自动跳转https显示404错误解决办法 含代码
一、问题 因项目需要,域名没有ssl证书,结果http访问时被强制定向到https前缀,结果会显示404 测试版本cefsharp126.x (x64) 框架 CefSharp.WinForms.NETCore 二、代码(核心代码) 如果请求url是http,且目标是https时,则阻止请求 //判断请求变化 if (url.StartsWith(<…...
RK 方案如何做到上电关机
针对RK方案,公版都是上电开机的,有时候有要求需要上电关机,按键开机,需要把PMU的VDC脚的相关电路去掉即可,只保留一个对地电容。这时候就是上电关机了。RP43/RP47/RP64 电阻都去掉。 沟通交流群QQ:71228861…...
基于量子通讯进行安全认证
8月16日,中国银行的一项发明专利“安全认证方法、装置、电子设备及计算机存储介质”授权公告。其申请于2022年6月29日,公布于2022年9月20日。据悉,该发明中应用了量子通讯/量子随机数相关技术。 事实上,近年来,有多家银行探索研究量子技术。在多家银行的2024半年报中,就…...
C语言贪吃蛇小游戏演示和说明
C语言贪吃蛇小游戏演示和说明 设计贪吃蛇游戏的主要目的是让大家夯实C语言基础,训练编程思维,培养解决问题的思路,领略多姿多彩的C语言。 游戏开始后,会在中间位置出现一条只有三个节点的贪吃蛇,并随机出现一个食物&am…...
C++三大特性——继承性(超万字详解)
目录 前言 一、封装 1. 封装(Encapsulation) 二、继承 1. 构造函数的调用顺序 原理: 2. 析构函数的调用顺序 原理: 3、派生类的隐藏 1. 成员函数隐藏 2. 成员变量隐藏 3. 基类函数的重载隐藏 三、多重继承问题 1. 构…...
electron使用npm install出现下载失败的问题
我在使用electron进行下载时,经常出现一个错误。 HTTPError: Response code 404 (Not Found) for https://registry.npmmirror.com/v21.4.4/electron-v21.4.4-win32-x64.zip 这个时候需要修改一些npm的配置。使用命令npm config list -ls 滑到下面,找到一…...
HT513 2.8W I2S 输入单声道D类音频功率放大器
1 特性 ● 电源供电 PVDD 2.5-6.5V; DVDD/AVDD 3.3V ● 灵活的音频输入: I2S,LJ, RJ TDM 输入 8,16,32,44.1,48,88.2,96,192kHz 采样频率输出功率: 1.40W(PVDD3.6V,RL4Ω,THDN10%) 2.80W(PVDD5.0V,RL4Ω,THDN10%) 4.70W(PVDD6.5V,RL4Ω,THDN10%) ● THDN0.08%(Po1W, …...
[PICO VR]Unity如何往PICO VR眼镜里写持久化数据txt/json文本
前言 最近在用PICO VR做用户实验,需要将用户实验的数据记录到PICO头盔的存储空间里,记录一下整个过程 流程 1.开启写入权限 首先开启写入权限:Unity->Edit->Player->安卓小机器人->Other Settings->Configuration->Wri…...
zico2打靶记录
一、环境搭建 下载地址:https://download.vulnhub.com/zico/zico2.ova 直接双击下载的.ova文件即可在VMware中打开 设置好保存路径后在虚拟机的设置中删除仅主机这个网卡 然后启动靶机 二、信息收集 扫描靶机ip arp-scan -l 扫描一下开放的端口 nmap -p- -sV…...
pick你的第一个人形机器人——青龙强化学习环境测试
文章目录 一、环境配置二、开始训练三、训练成果 最近感受到的大趋势是具身智能,强化学习,模仿学习做人形机器人,这个赛道很火,颇有前些年全力投入做自动驾驶的架势,正好最近用强化学习解决POMDP问题接触到了强化学习&…...
了解主机及进程资源占用情况、性能情况、性能瓶颈,TOP命令输出解释
列表前的字段解释 字段通俗解释top - 03:08:50 up 19:36当前时间是 03:08:50,系统已经运行了 19 小时 36 分钟1 user当前有 1 个用户登录使用系统load average: 0.00, 0.02, 0.00系统在过去 1 分钟、5 分钟和 15 分钟内平均的工作繁忙程度,数值越大表示越忙 对于一个 x个核的…...
UE5 学习系列(二)用户操作界面及介绍
这篇博客是 UE5 学习系列博客的第二篇,在第一篇的基础上展开这篇内容。博客参考的 B 站视频资料和第一篇的链接如下: 【Note】:如果你已经完成安装等操作,可以只执行第一篇博客中 2. 新建一个空白游戏项目 章节操作,重…...
接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?
一、核心优势:专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发,是一款收费低廉但功能全面的Windows NAS工具,主打“无学习成本部署” 。与其他NAS软件相比,其优势在于: 无需硬件改造:将任意W…...
最新SpringBoot+SpringCloud+Nacos微服务框架分享
文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的,根据Excel列的需求预估的工时直接打骨折,不要问我为什么,主要…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...























