JWT 从入门到精通
什么是 JWT
JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案
JSON Web Token Introduction - jwt.ioLearn about JSON Web Tokens, what are they, how they work, when and why you should use them.https://jwt.io/introduction
一、常见会话
cookie、session、token
-cookie:客户端浏览器的键值对
-session:服务的的键值对(djangosession表,内存中,文件,缓存数据库)
-token:服务的生成的加密字符串,如果存在客户端浏览器上,就叫cookie
-三部分:头,荷载,签名
-签发:登录成功,签发
-认证:认证类中认证
jwt (Json web token)
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
二、base64编码和解码
base64并不是一种加密反射,只是编码解码方式
- 字符串,可以转成base64编码格式:eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
- eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9 解码成base64
import json
import base64d = {'user_id': 1, 'username': "lqz"}d_str = json.dumps(d)print(d_str)
# # 对字符串进行bashe64 编码
res=base64.b64encode(bytes(d_str,encoding='utf-8'))
print(res) # eyJ1c2VyX2lkIjogMSwgInVzZXJuYW1lIjogImxxeiJ9# 解码
res=base64.b64decode('TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ=')
print(res)
ps:记住: base64 编码,长度一定是4的倍数。如果不够,用 = 补齐
base64的用途
- 互联网中,前后端数据交互,使用base64编码
- jwt 字符串使用base64编码
- 互联网中一些图片,使用base64编码
s = 'iVBORw0KGgoAAAANSUhEUgAAAMcAAADHCAIAAAAiZ9CRAAAHB0lEQVR42u3dwXakSAxEUf//T3v2MwuD4kmkch7Lsl1Q5KUrCHFO//y6udHbj6fArUvVT7Y92tN/fvnJG+K7qB3Pk/d5dajUEYan5cnxFE6LqlSlKlVtVFU7I9QnCcH1XQlP/mrAR21fFLjn76MqValKVatVhetKnQhqXV8dxsA1Rq3iq8umtoIFCapSlapUpaqHZy1MCdT9f1+8o0zj1UnTSVCVqlSlqv+zqnClqTMSxiA8vuClQ23htuYqValKVaoaUfVhM5t77SsmBmLQZGuANx2qUpWqVLVXVfh8la9c8wr5fJWqfEVVvnKwKmrrmwGHceqTW3oqgE42OAwDValKVarao+qQG13qVpy6NsKTEBb6fVPhvutZVapSlarWqaKKb/yRKTzeDeQPKgYN7IsauqtKVapS1QWqaneqeB6i/goPWFTW6StTqKYj+VyqUpWqVLVRVe2+nRo8Uzf5fXDx6gSfT1CFS8t0WVWqUpWqlquqfSTqUZ5D6oy+Qj9c6bA1CA9MVapSlaruVhWea7waGAhzuA+8SQ9r9/AkqEpVqlLVBaqobEE9mYQniVpLTl1s4fwb/1z4+VGVqlSlqgtUHVI0Uy1wON8NlyG8NnB5n+UqValKVao6T1WIqe85JEo53iZPzuPDqyUsOAonXFWqUpWqFqliv1Zbi288aVHHgz/LhQcjKleRz1epSlWqUtV5qqgb+MkGnEKJj8/xdptKok2XuqpUpSpVLVLV99QRFQ5q4CZPMXUOJ+NU+A/EH7lKVapSlapuUUUdN1VhU78T0sEvtoHGJBHz5FBVpSpVqWqjqvAcDTTpVCsdZjiqjK5VMFTAwifQqlKVqlS1TlV4344HGgo3khJA3ANFwCfR7Y+JjapUpSpVbVBFdesD5W94Lx0OjKmZNFVVhJfWQc8sqEpVqlLVR6rmJ5HlveOUqboc7wg+2VdyflSlKlWp6g5V4Vcv/ogSPooOe/O+hoIqQfrqldfduqpUpSpV3aKKWjP89phqivFj/mSK0Dfyb8lVqlKVqlQ1q6rvWZy+roGaf4fO+gbqkz1+zZCqVKUqVV2gKrzf7nslvJPHa+VPdvFJS55MWVSlKlWpaqMqvOENUwKuHP8Rta6f9PjUWqhKVapS1U2qaj11bT1q1XPf7Tr1kBkVjMLLBt9UpSpVqeomVVQPS8UOvM7om1tTY91P9oWHQlWpSlWqWqdqYFIbntnw7roPLt504LG1bwKtKlWpSlUXqKrd2w8MMtnv+44seJqPsJQZSuuqUpWqVHWMqr6ieZJF3wWAf+Rj+wjkSlCVqlSlqkWq8O/XvlxVyw1Uv1y76sJnniYpI2uqKlWpSlWLVHWPG8steV//HsaO2huGXqmpRl83pCpVqUpVN6minuChBpl9qQWvnvF6ZaDKCXehKlWpSlXrVFF5KJxo4lPhbxuKyfl3X+lQOL2qUpWqVLVIFbXVeuowUvSV9bU/p6D0lezhBfk6ratKVapS1cGqQg3U13O4MFQoxJNN2K0P9DWfpXVVqUpVqjpGFV4Q901ha0kLv1qo0v/bv+rt1lWlKlWp6jpV+Ci6j2lNQ5/yyWHwZNuuKlWpSlV3q6LuwAeKgIEeP1y80P1AQzGUq1SlKlWp6hhVeDQJQ8bADfPAA1vUqIDKnU0RWVWqUpWqNqoKb3Sptf+FNirD1YLRAKbamaeqeVWpSlWqukAVhanvCzu8pccffsJ/eTLVhZf6n59UVapSlapWq8KnwpMBKwwQ1C19OLvtq1eoXbzOVapSlapUdZ6q2vyy9hU+EJU+gVKLJrVwSV02+NRcVapSlaquVEV9u4coB5YhHJ9TFieLkvB9/vWKqlSlKlUtUtVXjofLEHa+YT1NLRU+QqYeaMPH+apSlapUtU7VwCM4fa00VQSEn4vSif9OX+B73a2rSlWqUtV5qmozV+pbOVy88OCpd6bu26lMSWXcwuqoSlWqUtVGVVSS6CuIQ7gD3MPWAI+b+KKoSlWqUtWVqqj2Fv/zgUYAL/Rr4PqiW3j1Pv9cqlKVqlS1SFVYH4S9ME4HbwSoywafx+M5uGVioypVqUpVB6uiAkTT8zod+YM66VQ/EobLyerkdVpXlapUpaoNqvoqbOQLuzWo4aPfvvDU9yNkTVWlKlWpapEqKkmEU8++N8Sn3eGVEB4z9SO8f1eVqlSlqr2qDrnJr53ivoFxmDaoyDWwLyRlqkpVqlLValXsuPG34T//oNpkinu4eLXDOKRbV5WqVKUqVeEjUmoY3DcjD4fTh4QnasCgKlWpSlWqCpchzARhwKIqj0+CI1WmJFeCqlSlKlWtVkV99YZTTyqIhDqpfVEj7b5WJRylqEpVqlLVXlVUm9yXJMJynEpseGr51iKbIFWlKlWpapEqNzdwU5Ubv/0DEut6+QvkIFgAAAAASUVORK5CYII='
res = base64.b64decode(s)
with open('code.png', 'wb') as f:f.write(res)
三、 JWT认证
在用户注册或登录后,我们想记录用户的登录状态,或者为用户创建身份认证的凭证。我们不再使用Session认证机制,而使用Json Web Token(本质就是token)认证机制
使用jwt认证和使用session认证的区别
加密原理
在对称加密的时代,加密和解密用的是同一个密钥,这个密钥既用于加密,又用于解密。这样做有一个明显的缺点,如果两个人之间传输文件,两个人都要知道密钥,如果是三个人呢,五个人呢?于是就产生了非对称加密,用一个密钥进行加密(公钥),用另一个密钥进行解密(私钥)
1.公钥私钥原理
张三有两把钥匙,一把是公钥,另一把是私钥。
张三把公钥送给他的朋友们李四、王五、赵六每人一把。
李四要给张三写一封保密的信。她写完后用张三的公钥加密,就可以达到保密的效果。
张三收信后,用私钥解密,就看到了信件内容。这里要强调的是,只要张三的私钥不泄露,这封信就是安全的,即使落在别人手里,也无法解密。
张三给李四回信,决定采用“数字签名”。他写完后先用Hash函数,生成信件的摘要(digest)。然后利用私钥将摘要进行加密,张三将这个签名,附在信件下面,一起发给李四。
李四收信后,取下数字签名,用张三的公钥解密,得到信件的摘要。由此证明,这封信确实是张三发出的。李四再对信件本身使用Hash函数,将得到的结果,与上一步得到的摘要进行对比。如果两者一致,就证明这封信未被修改过。
四、JWT生产公钥与私钥
找到JDK环境的keytool(证书管理工具)
生成私钥
keytool -genkeypair -alias test110 -keyalg RSA -keypass miyaomima -keystore xc.keystore -storepass miyaokumima
建值 | 解释说明 | 测试用例 |
-alias | 证书的别名 | test110 |
-keyalg | 使用的hash算法 | RSA |
-keypass | 密钥的访问密码 | miyaomima |
-keystore | 生成的文件的名字 | xc.keystore |
xc.keystore | 保存了生成的证书 | |
-storepass | 密钥库的访问密码 | miyaokumima |
Windows系统需以管理员身份运行
查看证书文件是否生成成功
查看密钥
keytool -list -keystore xc.keystore
删除别名
keytool -delete -alias test110 -keystore xc.keystore
生成公钥
配置openssl
Win32/Win64 OpenSSL Installer for Windows - Shining Light Productionshttp://slproweb.com/products/Win32OpenSSL.html找一个合适自己计算机版本的进行配置
点击下载
这里小编使用默认路径进行安装
配置path环境变量
本教程配置在C:\Program Files\OpenSSL-Win64\bin
cmd进入xc.keystore文件所在目录执行命令 | 右键终端打开
keytool -list -rfc --keystore xc.keystore | openssl x509 -inform pem -pubkey
将上边的公钥拷贝到文本public.key文件中,合并为一行,可以将它放到需要实现授权认证的工程中
Attention
证书文件不要放在有中文路径下
所有文字都要在同一行
五、项目实战
引入JWT的依赖
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-api</artifactId><version>0.10.5</version>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-impl</artifactId><version>0.10.5</version><scope>runtime</scope>
</dependency>
<dependency><groupId>io.jsonwebtoken</groupId><artifactId>jjwt-jackson</artifactId><version>0.10.5</version><scope>runtime</scope>
</dependency>
引入其他依赖
<dependency><groupId>joda-time</groupId><artifactId>joda-time</artifactId><version>2.9.4</version>
</dependency>
<dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.7.16</version>
</dependency>
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.54</version>
</dependency>
创建User对象
public class UserInfo {private Long id;//用户IDprivate String username;//用户名称private String role;//用户角色public Long getId() {return id;}public void setId(Long id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public String getRole() {return role;}public void setRole(String role) {this.role = role;}
}
创建JWT工具类
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.joda.time.DateTime;import java.security.PrivateKey;
import java.security.PublicKey;
import java.util.Base64;
import java.util.UUID;public class JwtUtils {private static final String JWT_PAYLOAD_USER_KEY = "user";/*** 私钥加密token** @param info 载荷中的数据* @param privateKey 私钥* @param expire 过期时间,单位分钟* @return JWT*/public static String generateTokenExpireInMinutes(Object info, PrivateKey privateKey, int expire) {return Jwts.builder()//claim: 往Jwt的载荷存入数据.claim(JWT_PAYLOAD_USER_KEY, ObjectUtil.toString(info))//往Jwt的载荷存入数据,设置固定id的key.setId(createJTI())//往Jwt的载荷存入数据,设置固定exp的key.setExpiration(DateTime.now().plusMinutes(expire).toDate())//设置token的签名.signWith(privateKey, SignatureAlgorithm.RS256).compact();}/*** 私钥加密token** @param info 载荷中的数据* @param privateKey 私钥* @param expire 过期时间,单位秒* @return JWT*/public static String generateTokenExpireInSeconds(Object info, PrivateKey privateKey, int expire) {return Jwts.builder().claim(JWT_PAYLOAD_USER_KEY, ObjectUtil.toString(info)).setId(createJTI()).setExpiration(DateTime.now().plusSeconds(expire).toDate()).signWith(privateKey, SignatureAlgorithm.RS256).compact();}/*** 公钥解析token** @param token 用户请求中的token* @param publicKey 公钥* @return Jws<Claims>*/private static Jws<Claims> parserToken(String token, PublicKey publicKey) {return Jwts.parser().setSigningKey(publicKey).parseClaimsJws(token);}private static String createJTI() {return new String(Base64.getEncoder().encode(UUID.randomUUID().toString().getBytes()));}/*** 获取token中的用户信息** @param token 用户请求中的令牌* @param publicKey 公钥* @return 用户信息*/public static <T> Payload<T> getInfoFromToken(String token, PublicKey publicKey, Class<T> userType) {Jws<Claims> claimsJws = parserToken(token, publicKey);Claims body = claimsJws.getBody();Payload<T> claims = new Payload<>();claims.setId(body.getId());claims.setInfo(JSONUtil.toBean(body.get(JWT_PAYLOAD_USER_KEY).toString(), userType));claims.setExpiration(body.getExpiration());return claims;}/*** 获取token中的载荷信息** @param token 用户请求中的令牌* @param publicKey 公钥* @return 用户信息*/public static <T> Payload<T> getInfoFromToken(String token, PublicKey publicKey) {Jws<Claims> claimsJws = parserToken(token, publicKey);Claims body = claimsJws.getBody();Payload<T> claims = new Payload<>();claims.setId(body.getId());claims.setExpiration(body.getExpiration());return claims;}
}
创建RSA工具类
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;public class RsaUtils {private static final int DEFAULT_KEY_SIZE = 2048;/*** 从文件中读取公钥** @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*/private static PublicKey getPublicKey(byte[] bytes) throws Exception {bytes = Base64.getDecoder().decode(bytes);X509EncodedKeySpec spec = new X509EncodedKeySpec(bytes);KeyFactory factory = KeyFactory.getInstance("RSA");return factory.generatePublic(spec);}/*** 获取密钥** @param bytes 私钥的字节形式* @return* @throws Exception*/private static PrivateKey getPrivateKey(byte[] bytes) throws NoSuchAlgorithmException, InvalidKeySpecException {bytes = Base64.getDecoder().decode(bytes);PKCS8EncodedKeySpec spec = new PKCS8EncodedKeySpec(bytes);KeyFactory factory = KeyFactory.getInstance("RSA");return factory.generatePrivate(spec);}/*** 根据密文,生存rsa公钥和私钥,并写入指定文件** @param publicKeyFilename 公钥文件路径* @param privateKeyFilename 私钥文件路径* @param secret 生成密钥的密文*/public static void generateKey(String publicKeyFilename, String privateKeyFilename, String secret, int keySize) throws Exception {KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance("RSA");SecureRandom secureRandom = new SecureRandom(secret.getBytes());keyPairGenerator.initialize(Math.max(keySize, DEFAULT_KEY_SIZE), secureRandom);KeyPair keyPair = keyPairGenerator.genKeyPair();// 获取公钥并写出byte[] publicKeyBytes = keyPair.getPublic().getEncoded();publicKeyBytes = Base64.getEncoder().encode(publicKeyBytes);writeFile(publicKeyFilename, publicKeyBytes);// 获取私钥并写出byte[] privateKeyBytes = keyPair.getPrivate().getEncoded();privateKeyBytes = Base64.getEncoder().encode(privateKeyBytes);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.exists()) {dest.createNewFile();}Files.write(dest.toPath(), bytes);}
}
创建PayLoad工具类
import java.util.Date;public class Payload<T>{private String id;private T info;private Date expiration;public String getId() {return id;}public void setId(String id) {this.id = id;}public T getInfo() {return info;}public void setInfo(T info) {this.info = info;}public Date getExpiration() {return expiration;}public void setExpiration(Date expiration) {this.expiration = expiration;}
}
创建测试类
import com.alibaba.fastjson.JSONObject;public class Test {private static final String localPath = "\\main\\java\\com\\coldwind\\xutils\\jwt\\";public static void generateKey() {String proPath = System.getProperty("user.dir") + "\\src";proPath = proPath.replaceAll("\\\\", "\\\\\\\\");String keyPath = proPath+ localPath;String priKey = keyPath + "private.key";String pubKey = keyPath + "public.key";String secret = "123456";try {RsaUtils.generateKey(pubKey, priKey, secret, 2048);} catch (Exception e) {e.printStackTrace();}}public static void test() throws Exception {String proPath = System.getProperty("user.dir") + "\\src";proPath = proPath.replaceAll("\\\\", "\\\\\\\\");String keyPath = proPath+localPath;UserInfo userInfo = new UserInfo();userInfo.setUsername("admin");userInfo.setId(1L);String token = JwtUtils.generateTokenExpireInMinutes(JSONObject.toJSONString(userInfo), RsaUtils.getPrivateKey(keyPath+"private.key"), 10);System.out.println(token);Payload<UserInfo> userInfoPayload = JwtUtils.getInfoFromToken(token, RsaUtils.getPublicKey(keyPath+"public.key"),UserInfo.class);System.out.println(JSONObject.toJSONString(userInfoPayload));}public static void main(String[] args) throws Exception {test();}}
第一步:先在执行目录下生成公钥、私钥
第二步:模拟私钥加密
第三部:模拟公钥解密
执行效果
eyJhbGciOiJSUzI1NiJ9.eyJ1c2VyIjoie1wiaWRcIjoxLFwidXNlcm5hbWVcIjpcImFkbWluXCJ9IiwianRpIjoiTXprMVpEQmtOR010TWpZMFpTMDBPREl3TFRsaFpEZ3ROamRqTkdNelkyUTVNVEE1IiwiZXhwIjoxNzE3ODk3NTU2fQ.TrsJToMTUpkP6DbtyCL16-2d1WTTxPmOhb4BQyAFB6_nUg94xKu6q-lSfZNi3e7BmGxNrJYYNUyJZxaMO20ZQ88OJdeYbNfZ8ixxv2zw8QrmIFTGzHLqximXvl6kMZWEd_ArKRi2ba5NDQlTAvqJfQSv5hjiY-Rug_RX_Pd4ak81kVWOYOhJUMvsfoVlp6typoiFSWdjp024mkux4GtQfexZy0_CbLTX5KI4bVioSgxREPAhH68bmx-LcQQ9GEtcCidEZu0FsA6ubqnE0IWw5g6TJhOnuNdZOT2QWsv9WPaxhOJllV1mAqeXwnJufSZa-VUYgVjQhNnAWXbcNBSUqA
{"expiration":1717897556000,"id":"Mzk1ZDBkNGMtMjY0ZS00ODIwLTlhZDgtNjdjNGMzY2Q5MTA5","info":{"id":1,"username":"admin"}}
相关文章:
JWT 从入门到精通
什么是 JWT JSON Web Token(JWT)是目前最流行的跨域身份验证解决方案 JSON Web Token Introduction - jwt.ioLearn about JSON Web Tokens, what are they, how they work, when and why you should use them.https://jwt.io/introduction 一、常见会…...
31-捕获异常(NoSuchElementException)
在定位元素的时候,经常会遇到各种异常,遇到异常又该如何处理呢?本篇通过学习selenium的exceptions模块,了解异常发生的原因。 一、发生异常 打开百度搜索首页,定位搜索框,此元素id"kw"。为了故意…...
使用Spring Boot设计对象存储系统
对象存储系统是一种以对象为存储单位的存储架构,适合存储大量非结构化数据,如图片、音视频文件、文档等。MinIO是一个高性能的对象存储系统,基于开源和云原生的设计理念。本文将讨论如何使用Spring Boot设计一个类似MinIO的对象存储系统。 目…...
Apple开发者macOS设备与描述文件Profile创建完整过程
安装并打开Apple Configurator 新建描述文件 输入macOS平台的描述文件的相关信息,然后选择证书 选择一个可用证书 存储描述文件 存储成功如下: 使用文本编辑器打开刚才保存的描述文件,找到设备名与UDID...
SpringBootWeb 篇-深入了解 Redis 五种类型命令与如何在 Java 中操作 Redis
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 Redis 概述 1.1 Redis 下载与安装 2.0 Redis 数据类型 3.0 Redis 常见五种类型的命令 3.1 字符串操作命令 3.2 哈希操作命令 3.3 列表操作命令 3.4 集合操作命令 …...
mysql设置允许外部ip访问,局域网IP访问
(支持MYSQL8版本) 1. 登录进入mysql;mysql -uroot -p输入密码进入 2. 输入以下语句,进入mysql库,查看user表中root用户的访问 use mysql; select host,user from user; 3. 更新user表中root用户域属性,…...
mac虚拟光驱工具:Daemon Tools for Mac
Daemon Tools for Mac是一款功能强大的虚拟光驱工具,它为用户提供了在Mac上模拟物理光驱的能力,从而方便用户处理各种光盘映像文件。以下是关于Daemon Tools for Mac的详细介绍: 守护进程工具:Daemon Tools不仅是一个简单的虚拟光…...
软考 系统架构设计师系列知识点之杂项集萃(32)
接前一篇文章:软考 系统架构设计师系列知识点之杂项集萃(31) 第51题 网络逻辑结构设计的内容不包括( )。 A. 逻辑网络设计图 B. IP地址方案 C. 具体的软硬件、广域网连接和基本服务 D. 用户培训计划 正确答案&am…...
Web--CSS基础
文章目录 定义方式选择器文本字体背景边框元素展示格式内边距与外边距盒子模型位置浮动flex布局响应式布局 定义方式 行内样式表 直接定义在style属性中,作用于当前标签 <img src "/imges/logo.jpg" alt "" style "width 400"…...
服务部署:Linux系统部署C# .NET项目
1. 安装 .NET SDK 首先,你需要在你的 Linux 系统上安装 .NET SDK。 Ubuntu系统: 下载 Microsoft 包配置文件 wget https://packages.microsoft.com/config/ubuntu/20.04/packages-microsoft-prod.deb -O packages-microsoft-prod.deb 这个命令使用 wge…...
【机器学习】基于卷积LSTM的视频预测
1. 引言 1.1 LSTM是什么 LSTM(Long Short-Term Memory)是一种特殊的循环神经网络(RNN)变体,旨在解决传统RNN在处理长序列数据时遇到的梯度消失和梯度爆炸问题。LSTM通过引入门控机制和细胞状态的概念,使得…...
细说wayland和X11
文章目录 协议介绍协议区别开发差异 Wayland和X11都是用于Linux和其他类Unix系统的显示服务器协议。它们负责在用户和应用程序之间的交互中管理屏幕的输出以及输入设备的输入。 协议介绍 X11通常称为X Window System,是一个历史悠久的显示服务器,自1987…...
数据结构:二叉树的实现
目录 二叉树的遍历方式 前序遍历: 中序遍历: 后序遍历: 二叉树的基本结构和功能 基本结构: 基本功能: 二叉树功能的实现思路 二叉树功能的实现 1、构建一个二叉树 2、二叉树的销毁 3、计算二叉树里的节点个数 4、得…...
Helm离线部署Rancher2.7.10
环境依赖: K8s集群、helm 工具 Rancher组件架构 Rancher Server 包括用于管理整个 Rancher 部署的所有软件组件。 下图展示了 Rancher 2.x 的上层架构。下图中,Rancher Server 管理两个下游 Kubernetes 集群 准备Rancher镜像推送到私有仓库 cat >…...
Linux目录的作用和常用指令
目录结构及其详细作用 / (根目录) Linux文件系统的起点,所有文件和目录都在其下。 /bin 存放系统启动和运行时所需的基本命令,如 ls, cp, mv, rm,这些命令在单用户模式下或系统崩溃时仍然可用。 /boot 包含启动引导加载器的文件和Linux内核…...
Nvidia/算能 +FPGA+AI大算力边缘计算盒子:隧道和矿井绘图设备
RockMass 正在努力打入采矿业和隧道工程利基市场。 这家位于多伦多的初创公司正在利用 NVIDIA AI 开发一款绘图平台,帮助工程师评估矿井和施工中的隧道稳定性。 目前,作为安全预防措施,地质学家和工程师会站在离岩石五米远的地方࿰…...
MySQL物理备份
目录 备份策略 全量备份 (Full Backup) 增量备份 (Incremental Backup) 差异备份 (Differential Backup) 使用 Percona XtraBackup 全量备份 步骤 1:全量备份 步骤 2:备份后处理(应用日志) 步骤 3:恢复备份 验…...
AWT常用组件
AWT中常用组件 前言一、基本组件组件名标签(Label类)Label类的构造方法注意要点 按钮(Button)Button的构造方法注意要点 文本框(TextField)TextField类的构造方法注意要点 文本域(TextArea)TextArea 的构造方法参数scrollbars的静态常量值 复选框&#x…...
CorelDRAW2024破解激活码序列号一步到位
亲们,今天给大家种草一个神奇的软件——CorelDRAW破解2024最新版!🎨这是一款专业级的矢量图形设计软件,无论你是平面设计师、插画师还是设计师,都能在这个软件中找到你需要的工具和功能。✨ 让我来给大家介绍一下这款软…...
Webpack前端打包工具详解
目录 Webpack前端打包工具详解一、Webpack 的作用二、Webpack 的安装和基本使用1. 安装 Webpack2. 创建 Webpack 配置文件3. 运行 Webpack 三、Webpack 核心概念1. 入口(Entry)2. 输出(Output)3. 加载器(Loaders&#…...
计网总结☞网络层
.................................................. 思维导图 ........................................................... 【Wan口和Lan口】 WAN口(Wide Area Network port): 1)用于连接外部网络,如互联…...
【全开源】云调查考试问卷系统(FastAdmin+ThinkPHP+Uniapp)
便捷、高效的在线调研与考试新选择 云调查考试问卷是一款基于FastAdminThinkPHPUniapp开发的问卷调查考试软件,可以自由让每一个用户自由发起调查问卷、考试问卷。发布的问卷允许控制问卷的搜集、回答等各个环节的设置,同时支持系统模板问卷ÿ…...
网络安全难学吗?2024该怎么系统学习网络安全?
学习网络安全需要循序渐进,由浅入深。很多人对网络安全进行了解以后,就打算开始学习网络安全,但是又不知道怎么去系统的学习。 网络安全本身的知识不难,但需要学习的内容有很多,其中包括Linux、数据库、渗透测试、等保…...
2 程序的灵魂—算法-2.4 怎样表示一个算法-2.4.6 用计算机语言表示算法
我们的任务是用计算机解题,就是用计算机实现算法; 用计算机语言表示算法必须严格遵循所用语言的语法规则。 【例 2.20】求 12345 用 C 语言表示。 main() {int i,t; t1; i2; while(i<5) {tt*i; ii1; } printf(“%d”,t); } 【例 2.21】求级数的…...
重生之我要精通JAVA--第八周笔记
文章目录 多线程线程的状态线程池自定义线程池最大并行数多线程小练习 网络编程BS架构优缺点CS架构优缺点三要素IP特殊IP常用的CMD命令 InetAddress类端口号协议UDP协议(重点)UDP三种通信方式 TCP协议(重点)三次握手四次挥手 反射…...
51单片机独立按键控制LED灯,按键按一次亮,再按一次灭
1、功能描述 独立按键控制LED灯,按键按一次亮,再按一次灭 2、实验原理 轻触按键:相当于是一种电子开关,按下时开关接通,松开时开关断开,实现原理是通过轻触按键内部的金属弹片受力弹动米实现接通和断开;…...
【上海大学计算机组成原理实验报告】七、程序转移机制
一、实验目的 学习实现程序转移的硬件机制。 掌握堆栈寄存器的使用。 二、实验原理 根据实验指导书的相关内容,实验箱系统的程序转移硬件机制在于,当LDPC有效时,如果此时DUBS上的值就是转移的目标地址,则此目标地址被打入PC&am…...
LLVM Cpu0 新后端7 第一部分 DAG调试 dot文件 Machine Pass
想好好熟悉一下llvm开发一个新后端都要干什么,于是参考了老师的系列文章: LLVM 后端实践笔记 代码在这里(还没来得及准备,先用网盘暂存一下): 链接: https://pan.baidu.com/s/1yLAtXs9XwtyEzYSlDCSlqw?…...
修复www服务trace漏洞
验证方式:curl -v -X TRACE ip:port,或使用其他接口调试工具如Postman 响应:状态行405 Method Not Allowed且响应体无内容 方案一:使用过滤器 若webserver是tomcat, 添加过滤器的方式有很多 Component public class TraceHttpMe…...
算法:101. 对称二叉树
对称二叉树 给你一个二叉树的根节点 root , 检查它是否轴对称。 示例 1: 输入:root [1,2,2,3,4,4,3] 输出:true示例 2: 输入:root [1,2,2,null,3,null,3] 输出:false提示: 树中节…...
素材网站开发/电脑系统优化软件排行榜
1.LK<(设备接入&管理) 固件升级全新改版固件升级全新改版,固件和产品关联,并支持固件版本统计。 之前固件升级无法查看固件版本分布,数据不透明,会给用户造成困扰,本次进行了全新改版!固件都已根…...
整形网站专题素材/公司网站建设流程
JAVA面向对象基础 1、说一下什么是面向对象 面向对象是一种编程思想,它是相对于面向过程而言的,从执行者变为了指挥者,通过这种思想来将生活中复杂的事情简单化 面向对象就是把一个对象抽象成类,具体来说就是把一个对象的静态特…...
wordpress 伪静态原理/石家庄网站建设
日志库简介 最重要的一点是 区分日志系统和日志门面;其次是日志库的使用, 包含配置与API使用;配置侧重于日志系统的配置,API使用侧重于日志门面;最后是选型,改造和最佳实践等 日志库之日志系统 java.util.logging (JUL) JDK1.4 …...
新网站如何做免费推广/企业网络推广的方式有哪些
背景: 第三方开发,正常处理发送的数据,但是后面老是跟着“公众号提示该公众号暂时无法提供服务” 解决办法: 在第三方接收的代码文件中加上:ob_clean(); 注意如果你不是第三方开发,只是微信的开发ÿ…...
潍坊公司网站制作/宝鸡百度seo
按照预定的版本计划,前天GitLab官方博客宣布GitLab 12.8发布。新版本继续加强DevOps功能及其生命周期的管理,包括了日志浏览器、NuGet软件包和遵从性活动等。更详细功能,请随虫虫一起来学习。主要功能新的Log Explorer进行日志汇聚管理(ULTIM…...
apt 安装wordpress/故事式的软文广告例子
创建企业网站就如同写一篇文章,第一步要写好提纲,确立主题。企业网站的题材确定后,要想合理地组织内容并且吸引人们登陆网站进行查询和浏览,就需要建立企业网站的索引。索引应该能够将网站的主体明确表示出来。网站在设立栏目时要…...