RSA加密,解密,加签及验签
目录
1.说明
2.加密和加签的区别
3.后端加密,解密,加签及验签示例
4.前端加密,解密,加签及验签示例
5.前端加密,后端解密,前端加签,后端验签
6.注意事项
1.说明
RSA算法是一种非对称加密算法,与对称加密算法不同的是,RSA算法有两个不同的密钥,一个是公钥,一个是私钥。
公钥是公开的,可以多人持有;私钥是保密的,只有自己持有。
加密常用的密钥长度有1024,2048,3072,4096。密钥长度越长,加密的强度也就越强,性能也会越低。可以使用1024或2048位的密码。
2.加密和加签的区别
①加密是防止信息泄露,确保数据传输的安全,如前端输入的一些账号,密码,卡号等敏感信息,必须加密后传输。
加签是防止信息被篡改,确保是发送方传递的数据。
②通过公钥进行加密传输,然后接收方使用私钥进行解密。
通过私钥进行加签,然后接收方使用公钥进行验签。
③加密是可逆的,也就是说加密后的密文可以进行解密。
加签是不可逆的,只能通过验签来验明真伪。
④加密是明文长度是有限制的,明文的最大长度=密文长度-11(单位是字节),当设置密钥为1024位时,1024/8-11=117字节,所以明文的最大长度为117个字节,解密的最大长度为127个字节,相差11个字节是因为加密时使用了填充模式。
加签是没有长度限制的。
3.后端加密,解密,加签及验签示例
①引入依赖
<dependency><groupId>commons-codec</groupId><artifactId>commons-codec</artifactId><version>1.14</version></dependency>
②工具类
package com.example.utils;import java.io.ByteArrayOutputStream;
import java.security.KeyFactory;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import javax.crypto.Cipher;import org.apache.commons.codec.binary.Base64;/*** @Author linaibo* @Date 2024/2/17 16:26* @Version 1.0*/
public class RsaTool {/*** 16 * RSA最大加密明文大小* 17*/private static final int MAX_ENCRYPT_BLOCK = 117;/*** 21 * RSA最大解密密文大小* 22*/private static final int MAX_DECRYPT_BLOCK = 128;/*** 26 * 获取密钥对* 27 ** 28 * @return 密钥对* 29*/public static KeyPair getKeyPair() throws Exception {KeyPairGenerator generator = KeyPairGenerator.getInstance("RSA");generator.initialize(1024);return generator.generateKeyPair();}/*** 37 * 获取私钥* 38 ** 39 * @param privateKey 私钥字符串* 40 * @return* 41*/public static PrivateKey getPrivateKey(String privateKey) throws Exception {KeyFactory keyFactory = KeyFactory.getInstance("RSA");byte[] decodedKey = Base64.decodeBase64(privateKey.getBytes());PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(decodedKey);return keyFactory.generatePrivate(keySpec);}/*** 50 * 获取公钥* 51 ** 52 * @param publicKey 公钥字符串* 53 * @return* 54*/public static PublicKey getPublicKey(String publicKey) throws Exception {KeyFactory keyFactory = KeyFactory.getInstance("RSA");byte[] decodedKey = Base64.decodeBase64(publicKey.getBytes());X509EncodedKeySpec keySpec = new X509EncodedKeySpec(decodedKey);return keyFactory.generatePublic(keySpec);}/*** 63 * RSA加密* 64 ** 65 * @param data 待加密数据* 66 * @param publicKey 公钥* 67 * @return* 68*/public static String encrypt(String data, PublicKey publicKey) throws Exception {Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.ENCRYPT_MODE, publicKey);int inputLen = data.getBytes().length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offset = 0;byte[] cache;int i = 0;// 对数据分段加密while (inputLen - offset > 0) {if (inputLen - offset > MAX_ENCRYPT_BLOCK) {cache = cipher.doFinal(data.getBytes(), offset, MAX_ENCRYPT_BLOCK);} else {cache = cipher.doFinal(data.getBytes(), offset, inputLen - offset);}out.write(cache, 0, cache.length);i++;offset = i * MAX_ENCRYPT_BLOCK;}byte[] encryptedData = out.toByteArray();out.close();// 获取加密内容使用base64进行编码,并以UTF-8为标准转化成字符串// 加密后的字符串return new String(Base64.encodeBase64String(encryptedData));}/*** 96 * RSA解密* 97 ** 98 * @param data 待解密数据* 99 * @param privateKey 私钥* 100 * @return* 101*/public static String decrypt(String data, PrivateKey privateKey) throws Exception {Cipher cipher = Cipher.getInstance("RSA");cipher.init(Cipher.DECRYPT_MODE, privateKey);byte[] dataBytes = Base64.decodeBase64(data);int inputLen = dataBytes.length;ByteArrayOutputStream out = new ByteArrayOutputStream();int offset = 0;byte[] cache;int i = 0;// 对数据分段解密while (inputLen - offset > 0) {if (inputLen - offset > MAX_DECRYPT_BLOCK) {cache = cipher.doFinal(dataBytes, offset, MAX_DECRYPT_BLOCK);} else {cache = cipher.doFinal(dataBytes, offset, inputLen - offset);}out.write(cache, 0, cache.length);i++;offset = i * MAX_DECRYPT_BLOCK;}byte[] decryptedData = out.toByteArray();out.close();// 解密后的内容return new String(decryptedData, "UTF-8");}/*** 129 * 签名* 130 ** 131 * @param data 待签名数据* 132 * @param privateKey 私钥* 133 * @return 签名* 134*/public static String sign(String data, PrivateKey privateKey) throws Exception {byte[] keyBytes = privateKey.getEncoded();PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PrivateKey key = keyFactory.generatePrivate(keySpec);// 不同的签名算法Signature signature = Signature.getInstance("MD5withRSA");// Signature signature = Signature.getInstance("MD2withRSA");// Signature signature = Signature.getInstance("SHA1withRSA");// Signature signature = Signature.getInstance("SHA224withRSA");// Signature signature = Signature.getInstance("SHA256withRSA");// Signature signature = Signature.getInstance("SHA384withRSA");// Signature signature = Signature.getInstance("SHA512withRSA");signature.initSign(key);signature.update(data.getBytes());return new String(Base64.encodeBase64(signature.sign()));}/*** 147 * 验签* 148 ** 149 * @param srcData 原始字符串* 150 * @param publicKey 公钥* 151 * @param sign 签名* 152 * @return 是否验签通过* 153*/public static boolean verify(String srcData, PublicKey publicKey, String sign) throws Exception {byte[] keyBytes = publicKey.getEncoded();X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);KeyFactory keyFactory = KeyFactory.getInstance("RSA");PublicKey key = keyFactory.generatePublic(keySpec);// 不同的签名算法Signature signature = Signature.getInstance("MD5withRSA");// Signature signature = Signature.getInstance("MD2withRSA");// Signature signature = Signature.getInstance("SHA1withRSA");// Signature signature = Signature.getInstance("SHA224withRSA");// Signature signature = Signature.getInstance("SHA256withRSA");// Signature signature = Signature.getInstance("SHA384withRSA");// Signature signature = Signature.getInstance("SHA512withRSA");signature.initVerify(key);signature.update(srcData.getBytes());return signature.verify(Base64.decodeBase64(sign.getBytes()));}
}
③使用
package com.example.utils;import java.security.KeyPair;
import org.apache.commons.codec.binary.Base64;/*** @Author linaibo* @Date 2024/2/17 16:30* @Version 1.0*/
public class TestRsa {public static void main(String[] args) throws Exception {KeyPair keyPair = RsaTool.getKeyPair();String privateKey = new String(Base64.encodeBase64(keyPair.getPrivate().getEncoded()));String publicKey = new String(Base64.encodeBase64(keyPair.getPublic().getEncoded()));System.out.println("公钥:" + publicKey);System.out.println("私钥:" + privateKey);String data = "需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字";String encrypt = RsaTool.encrypt(data, RsaTool.getPublicKey(publicKey));System.out.println("加密后:" + encrypt);String decrypt = RsaTool.decrypt(encrypt, RsaTool.getPrivateKey(privateKey));System.out.println("解密后:" + decrypt);String sign = RsaTool.sign(data, RsaTool.getPrivateKey(privateKey));System.out.println("签名后:" + sign);boolean verify = RsaTool.verify(data, RsaTool.getPublicKey(publicKey), sign);System.out.println("验签结果" + verify);}
}
结果:
公钥:MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQD5Wa+wf44UliJLXLQ0UUTZXaH1EZv1bHM4nNSV2xVQY2RN8dKLgQ1J71y+90vJjusi0rOqfFdni2UU3VtnMdtYOYXbhsV14oFtU+3+gWYK28KlqOd5rtjjNR2Vv0sPDaZ+Lfdsq6+p5BpNjtWApPM9ghXj0S6BM3GWjsftNPM/IwIDAQAB
私钥:MIICdwIBADANBgkqhkiG9w0BAQEFAASCAmEwggJdAgEAAoGBAPlZr7B/jhSWIktctDRRRNldofURm/Vsczic1JXbFVBjZE3x0ouBDUnvXL73S8mO6yLSs6p8V2eLZRTdW2cx21g5hduGxXXigW1T7f6BZgrbwqWo53mu2OM1HZW/Sw8Npn4t92yrr6nkGk2O1YCk8z2CFePRLoEzcZaOx+008z8jAgMBAAECgYB0hwA+6G1am4rtUyZ36J7XQhWk9JTAzezOwSPr4FWGmtxOPLubLDUsnyrlp6YITL0AKh2Ch9dE8XTMmmHTyQ3qsdjn5gXhxf2WBSNGKdpp9kO/x6NgfcsT71e9luHfhA2eviN9EQWXriOLRECPmvGGwcvRrMJhS3lz/xyFaSUvkQJBAP4hO35zbkF9rTXfX/01RsUlyPBMmBwcpLft6oxjMq2hRmO7GCEpX8qaEdG3ODKDildzbXUjN76c+ynL61jYlXkCQQD7L3MY2OgPOGSgRhwUKceaBXQVnl2Y5BEhq5HERFRBWfWiJUzsEHoY30SGfvw6jsegM9Crd6f+aEzaHBMyyV57AkEAhkt3ji5f4JoSk7qUllG2MW7zThGb/JcicNR4s3GkkV79vKxdZwDfT0i2C/Zf60naLLah7FoNFl0M2ZyapVvnOQJBALFc++SbpKC6rTMOzlzec3aqSyHIxUZkJESmJTN1HBlZMDziIcK+j7hoTra5i9i9YPAaJkotH45gj4OjN1sxHWkCQCT6vx4dt5t92nIw+O0Hfwh6wY3qDz66Aq+7S3iAda04PqkECh0J30gzEcs2G8l8vkpihnAQtCtRANhkzqfDNu8=
加密后:8LbPWfiOb2iSah4Roq58mVLujvELI6BhLvOfm/jRCfMhuoEDWzfVpI9RFnPmIr43wQwDtFqCLAIDHpMggI21F4e59fj2/XTviUrUdxb/11qkhw+9ovELyhOSh85PNvhSv+F7nnn1kytAdT54chKtxgGhd6ZzFs7LZx1qoyGA/ypC9Bl5ZiT4ZECNOR6ZlOK8v5aVfiwZUz9iKso5COF0DFf4rlBSKoteH2muhJWkNC+SxLqjOjieCTrWaFqERSFKtnRoCqCAnNXpYn3gSZDilp6n3UhHsW8MPQ0rn+UYY0D4JepBXIk6VrDXfRiPKrw4wCVXTDYSsL6RoZ36WUW5Azf3sCKr1PRe5Gw1CtpoAYavKqxr0QD7ShheWxBX1Jbb3uXwr/FOxlJ9GlrTr6ZBhHomz2jEV7pgmBfMvsg7g6hAfinSUk6tM60gw3zJT6Bq0M29MNtI04Cbj0i5aXCPpTKyT1wvVW+oZrCvfjPIimQ9RmqmhBAS1/qvETS6K5+c
解密后:需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字需要加密的文字
签名后:FgpCHgRZg0AoR747wvDDBbPhYeVUCEJfRaJ3tGVJY3QplddTxprtMHYFQalLK3vVP5Dpo/6bMAzQyu8Y4oaArqtYpoURhPnvr4QXTH+fR8MG8PGYc1S11ysAuDPbsb6geAvHRFsspjGJ9oLH2nHBnZzMQ62HGZ+RzAKING219SY=
验签结果true
4.前端加密,解密,加签及验签示例
前端这块主要采用jsencrypt
进行加解密,jsrsasign
用来生成密钥对、加签验签。
①引入依赖
// JSEncrypt
pnpm i jsencrypt// jsrsasign
pnpm i jsrsasign
②加密,解密,加签及验签工具类
import JSEncrypt from "jsencrypt";
import JsRsaSign from "jsrsasign";/*** RSA加密* @param publicKey 公钥* @param plainText 明文* @returns {*} 密文*/
export function encryptByRSA(publicKey, plainText) {const encryptor = new JSEncrypt();encryptor.setPublicKey(publicKey);return encryptor.encrypt(plainText);
}/*** RSA解密* @param privateKey 私钥* @param cipherText 密文* @returns {*} 明文*/
export function decryptByRSA(privateKey, cipherText) {const decrypter = new JSEncrypt();decrypter.setPrivateKey(privateKey);return decrypter.decrypt(cipherText);
}/*** 生成RSA密钥对,填充模式为PKCS8。* 更多模式参考:<a href="https://kjur.github.io/jsrsasign/api/symbols/KEYUTIL.html">https://kjur.github.io/jsrsasign/api/symbols/KEYUTIL.html</a>* @returns {{privateKey: (string|string|*), publicKey: (string|string|*)}}*/
export function generateRsaKeyWithPKCS8() {const keyPair = JsRsaSign.KEYUTIL.generateKeypair("RSA", 1024);const privateKey = JsRsaSign.KEYUTIL.getPEM(keyPair.prvKeyObj, "PKCS8PRV");const publicKey = JsRsaSign.KEYUTIL.getPEM(keyPair.pubKeyObj);return { privateKey, publicKey };
}
/*** SHA256和RSA加签* @param privateKey 私钥* @param msg 加签内容* @returns {string} Base64编码签名内容*/
export function signBySHA256WithRSA(privateKey, msg) {const key = JsRsaSign.KEYUTIL.getKey(privateKey);const signature = new JsRsaSign.KJUR.crypto.Signature({alg: "MD5withRSA",// alg: "SHA1withRSA",// alg: "SHA224withRSA",// alg: "SHA256withRSA",// alg: "SHA384withRSA",// alg: "SHA512withRSA",// alg: "RIPEMD160withRSA",});signature.init(key);signature.updateString(msg);// 签名后的为16进制字符串,这里转换为16进制字符串return JsRsaSign.hextob64(signature.sign());
}/*** SHA256和RSA验签* @param publicKey 公钥:必须为标准pem格式。如果是PKCS1格式,必须包含-----BEGIN RSA PRIVATE KEY-----,如果是PKCS8格式,必须包含-----BEGIN PRIVATE KEY-----* @param base64SignStr Base64编码签名字符串* @param msg 原内容* @returns {boolean} 是否验签通过*/
export function verifyBySHA256WithRSA(publicKey, base64SignStr, msg) {const key = JsRsaSign.KEYUTIL.getKey(publicKey);const signature = new JsRsaSign.KJUR.crypto.Signature({alg: "MD5withRSA",// alg: "SHA1withRSA",// alg: "SHA224withRSA",// alg: "SHA256withRSA",// alg: "SHA384withRSA",// alg: "SHA512withRSA",// alg: "RIPEMD160withRSA",});signature.init(key);signature.updateString(msg);// 需要将Base64进制签名字符串转换成16进制字符串return signature.verify(JsRsaSign.b64tohex(base64SignStr));
}
③使用
<!-- eslint-disable vue/require-v-for-key -->
<script setup>
import Component1 from '@/components/Component1.vue';
import Component2 from '@/components/Component2.vue';
import Component3 from '@/components/Component3.vue';
import {useCountStore} from '@/store/modules/count/countStore';
import {useChannelStore} from '@/store/modules/channel/channelStore'
import {ref} from 'vue';
import testStore from './components/testStore.vue';
import {encryptByRSA,decryptByRSA,generateRsaKeyWithPKCS8,signBySHA256WithRSA,verifyBySHA256WithRSA} from '@/utils/crypto';const {privateKey, publicKey} = generateRsaKeyWithPKCS8();
console.log(`生成的私钥为:\n${privateKey}`);
console.log(`生成的公钥为:\n${publicKey}`);const cipherText = encryptByRSA(publicKey, "123456789----------123456789");
console.log(`test加密后的内容为:\n${cipherText}`);const plainText = decryptByRSA(privateKey, cipherText);
console.log(`解密后的内容为:\n${plainText}`);const signature = signBySHA256WithRSA(privateKey, "123456789----------123456789");
console.log(`生成的签名:\n${signature}`);const isVerified = verifyBySHA256WithRSA(publicKey, signature, "123456789----------123456789");
console.log(`是否验签通过:${isVerified}`);</script><template><div> </div>
</template><style scoped>
</style>
数字签名有多种,加签及验签使用的数字签名要一致。
结果:
5.前端加密,后端解密,前端加签,后端验签
前后端的工具类直接使用上面的即可。加签的数字签名确保前后端的一致。
String pri = "MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBAL03PU6h7DfX0pGb" +"hFak0gAPJVSCOFjy0vXfPefm88wr9gx3aIGqRNyubdtw37jG3jUF+b1d/5M5bVB1" +"YB23cs5FkjmIVwdiUoHgRPCUwDoet6ZpamDSdpLTWqmC4uDb9R8FLRI1Q2h2cMBV" +"T+TR6D+fFHRLOJFvlrh+juvcZvonAgMBAAECgYBSoWj4ieXqjSm7xLqKS/gZZoPa" +"3/NThNdz4EXcnBMjup782ricx4rDBLmc9zH8M3yekzl45S/TT2TZmiibUZ2kjVYs" +"ZV3GoVzVbBek9vStDHVlVjGQvUnVbMuoKTpcEs0efjIz3Su0NQsxLyb4+KZFMzts" +"H/C4JOBE0kb/cuhhIQJBAPeMvUg61pvR2IfrTiREtiN9uKi0b+pSDH5E+sq89rET" +"QjC65a209pVoWkdx4HBKIK4KL+saLAI8w9b1fZhPGc0CQQDDrLzM2JFjCpC4g9gx" +"NdFTZmwFaqKrAkKB3tw492PgvLZWbO6HocDWRMYi1RtkBYq7FFzRftIAr7QDxKLz" +"oJ/DAkAX7NRGbNldCfUBfe55duKbn4T/WSEP5ooqkgQjIAw/pPrattWH6luCqSlA" +"inMEp0VtTLLA6DCkrrbGyccvt0VpAkEAuKnXT9b+diKta4T5zY9FqliZjw8QzySF" +"0XyaBqTqPFi8F5ocDiJIE6658nt9qwpT37Qa2Ja/52fqEjhLtHIc8wJAB1T7XQ1s" +"olFqeE3T9n/3NfbvSw66Act2kYS+KrGYtrDMjSBH+s7rIN7DWAz/zlCRPQ0EyY9w" +"gcEyHHFoKN2vDA==";String pub = "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC9Nz1Ooew319KRm4RWpNIADyVU" +"gjhY8tL13z3n5vPMK/YMd2iBqkTcrm3bcN+4xt41Bfm9Xf+TOW1QdWAdt3LORZI5" +"iFcHYlKB4ETwlMA6HremaWpg0naS01qpguLg2/UfBS0SNUNodnDAVU/k0eg/nxR0" +"SziRb5a4fo7r3Gb6JwIDAQAB";String decrypt1 = RsaTool.decrypt("jNlG4S6w4xrq62todeiXJoPoCrQ0WRn1wq2WkKm+s7bPFkYnYDARebVh8tbSl0OL/FIBE1HytI6jRnzo6CxkdMVPdUh3W1gcAMOLtYEdOOW8g749/vMH6ptBYgG7I02TdRTilCKrWxG1yBUU/2vz73w+Ges4l2bw+s87zr7WXh8=", RsaTool.getPrivateKey(pri));System.out.println("解密后:" + decrypt1);boolean verify1 = RsaTool.verify("123456789----------123456789", RsaTool.getPublicKey(pub), "VECLGuhG59fwhE3ikT2mpO/CTf/9EMXRdL3U308j98jYQLx1WamjMJmBmPF/nf8b6D0Uv2TxmPOnLAw/iFe+6f1oC62DFzR77J7agomi8cG0itcxY37WhExv4tkrgxf8DMH9uZ7SoYMTtXoSD4PtJIDxJnvWo5/4QmqtnZfA3d4=");System.out.println("验签结果" + verify1);
结果:
解密后:123456789----------123456789
验签结果true
6.注意事项
①因为加密的明文长度限制,所以需要分段进行加密。
②公钥加密,私钥解密;私钥加签,公钥验签
③后端RSA的数字签名算法主要有以下两种:
- MD系列 。主要包括MD2withRSA和MD5withRSA。
- SHA系列 。主要包括SHA1withRSA、SHA224withRSA、SHA256withRSA、SHA384withRSA、SHA512withRSA。
数字签名算法具有安全性、抗否认性的特点,它是一种带有密钥(公钥、私钥)的消息摘要算法,用于验证数据完整性、认证数据来源、抗否认等。
④前后端加签使用的签名算法略有区别,可以选择使用前后端都有的数字签名。加签和验签使用的数字签名算法要一致。
参照:
RSA加密、解密、签名、验签的原理及方法_rsa解密-CSDN博客
数字签名算法MD5withRSA-CSDN博客
前后端RSA互相加解密、加签验签、密钥对生成(Java)_jsencrypt java-CSDN博客
相关文章:

RSA加密,解密,加签及验签
目录 1.说明 2.加密和加签的区别 3.后端加密,解密,加签及验签示例 4.前端加密,解密,加签及验签示例 5.前端加密,后端解密,前端加签,后端验签 6.注意事项 1.说明 RSA算法是一种非对称加密…...

【C++搜索】BFS:走迷宫
题目描述 一个迷宫由R行C列格子组成,有的格子里有障碍物,不能走;有的格子是空地,可以走。 给定一个迷宫,求从左上角走到右下角最少需要走多少步(数据保证一定能走到)。只能在水平方向或垂直方向走,不能斜着…...

SpringMVC 的参数绑定之list集合、Map
标签中name属性的值就是pojo类的属性名 参数绑定4 list [对象] <form action"teaupd.do" method"post"> <c:forEach items"${list}" var"tea" varStatus "status"> 教师编号:<input…...

Code Composer Studio (CCS) - Current and Local Revision
Code Composer Studio [CCS] - Current and Local Revision References 鼠标放在文件内的任意位置,鼠标右键 -> Compare With -> Local History -> Revision Time. References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/...

Vue实现多个input输入,光标自动聚焦到下一个input
遇到一个需求,需要实现和移动端短信输入一样,输入内容后,光标会进入下一个输入框 需要用到2个事件 keydown事件发生在键盘的键被按下的时候 keyup 事件在按键被释放的时候触发 <template><div class"box"><el-fo…...

人工智能技术应用笔记(二):OpenAI SORA文生视频模型技术报告全文中英对照 (GPT4翻译+人工润色)
目录 Video generation models as world simulators(视频生成模型作为世界模拟器) Turning visual data into patches (将视觉数据转换为图像块) Video compression network (视频压缩网络) Spacetim…...

Linux-系统资源管理的命令
目录 查看CPU:more /proc/meminfo 查看内存数据:free -m / free -h 查看系统版本:more /etc/issue 查看操作系统的类型:uname -a 查看主机名称:hostname 查看磁盘空间:df -h 查看某个目录空间…...

Html的<figure><figcaption>标签
Html的<figure><figcaption>标签 示例一: <figure><figcaption>figcaption001, fig标题1 </figcaption><figcaption>figcaption002, fig标题2 </figcaption><div style"width:calc(100px*2); height:calc(100px*2); back…...

Selenium实现多页面切换
当使用 Selenium 进行自动化测试或爬取数据时,有时需要处理多个页面之间的切换。以下是一些可能需要多页面切换的情况: 1、打开新窗口/页面: 在当前页面上点击链接、按钮或执行某些操作时,可能会打开一个新的窗口或页面。此时&a…...

Electron实战之菜单与托盘
菜单、托盘是桌面端应用必备的功能之一,我们通常会在菜单上配置应用常用的:偏好设置、显示隐藏、打开文件等功能,在托盘内设置:退出、重启、帮助等辅助性功能,帮助用户方便快捷地控制应用的一些系统功能。系统托盘实际…...

【Java EE初阶十六】网络原理(一)
在网络原理中主要学习TCP/IP四层模型中的重点网络协议 1. 应用层 1.1 应用程序与协议 应用层是和程序员接触最密切的; 应用程序:在应用层这里,很多时候都是程序员自定义应用层协议(步骤:1、根据需求,明确…...

51_蓝桥杯_led流水灯
一 原理图分析 二 三八译码器工作原理 三八译码器:3个输入控制8路互斥的低电平有效输出。 C B A 输出 0 0 0 Y0 0 0 1 Y1 0 1 0 Y2 0 1 1 Y3 1 0 0 Y4 1 0 1 Y5 1 1 0 Y6 1 1 1 Y7 三 锁存器工作原理 锁存器:当使…...

⭐北邮复试刷题589. N 叉树的前序遍历__DFS (力扣每日一题)
589. N 叉树的前序遍历 给定一个 n 叉树的根节点 root ,返回 其节点值的 前序遍历 。 n 叉树 在输入中按层序遍历进行序列化表示,每组子节点由空值 null 分隔(请参见示例)。 示例 1: 输入:root [1,null,…...

php伪协议之phar
一.phar协议 用于将多个 PHP 文件、类、库、资源(如图像、样式表)等打包成一个单独的文件。这个归档文件可以像其他 PHP 文件一样被包含(include)或执行。PHAR 归档提供了一种方便的方式来分发和安装 PHP 应用程序和库,…...

蓝桥杯电子类单片机提升三——NE555
目录 单片机资源数据包_2023 一、NE555和定时器工作模式 1.NE555的介绍 2.定时器的计数模式 二、NE555频率读取代码的实现 1.定时器0初始化 2.通过读取TH0和TL0来读取频率 3.通过中断读取频率 三、完整代码演示 通过读取TH0和TL0来读取频率 main.c 通过中断读取频…...

发掘GPT-4商业创新的潜力
GPT-4在商业创新方面的应用潜力巨大,它能够基于庞大的训练数据集和强大的语言生成能力,协助企业或个人用户在多个商业场景中推动创新: 市场分析与战略规划:GPT-4可以对历史数据、行业趋势、竞争对手信息进行深度分析,并…...

LeetCode42.接雨水(单调栈)
题目 给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。 示例 : 输入:height [0,1,0,2,1,0,1,3,2,1,2,1] 输出:6 解释:上面是由数组 [0,1,0,2,1,0,1,3,2,…...

黄东旭:“向量数据库”还是“向量搜索插件 + SQL 数据库”?丨我对 2024 年数据库发展趋势的思考
本文由 PingCAP 黄东旭撰写,讨论了数据库技术在 2023 年的快速变革,并对 2024 年的数据库发展趋势进行了预测。文章重点关注了 GenAI 时代对数据库的影响,提出了在数据库选择上的两种路径:“向量数据库”和“向量搜索插件 SQL 数…...

Spark编程实验五:Spark Structured Streaming编程
目录 一、目的与要求 二、实验内容 三、实验步骤 1、Syslog介绍 2、通过Socket传送Syslog到Spark 3、Syslog日志拆分为DateFrame 4、对Syslog进行查询 四、结果分析与实验体会 一、目的与要求 1、通过实验掌握Structured Streaming的基本编程方法; 2、掌握…...

【已解决】引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突。
这种问题产生一般都会手足无措,包括笔者,但是不要慌,这种问题一般都是内存泄漏引起的。例如读者要访问一个已经被析构或者释放的变量,当然访问不了,导致存在问题。这时候读者应该从哪里产生内存泄漏这方面进行考虑&…...

Python Flask高级编程之RESTFul API前后端分离(学习笔记)
Flask-RESTful是一个强大的Python库,用于构建RESTful APIs。它建立在Flask框架之上,提供了一套简单易用的工具,可以帮助你快速地创建API接口。Flask-RESTful遵循REST原则,支持常见的HTTP请求方法,如GET、POST、PUT和DE…...

Windows如何打开投影到此电脑
1.首先点开设置 找到系统 点击投影到此电脑,如果这3行都显示灰色说明没有开启。 2.如何开启投影到此电脑 ①回到设置,点击应用 ②点击可选应用 ③ 安装无线显示器 投影设置可以和我一样...

【BUG】段错误
1. 问题 8核工程,核4在运行了20分钟以上,发生了段错误。 [C66xx_4] A00x53 A10x53 A20x4 A30x167e A40x1600 A50x850e2e A60x845097 A70xbad9f5e0 A80x0 A90x33 A100x53535353 A110x0 A120x0 A130x0 A140x0 A150x0 A160x36312e35 A170x20 A180x844df0 …...

深入理解指针(3)
目录 一、 字符指针变量二、 数组指针变量1.数组指针变量是什么?2.数组指针变量怎么初始化? 三、 二维数组传参的本质四、 函数指针变量1. 函数指针变量的创建2.函数指针变量的使用3.typedef关键字 五、 函数指针数组六、 转移表 一、 字符指针变量 在指针的类型中…...

ssm在线学习平台-计算机毕业设计源码09650
目 录 摘要 1 绪论 1.1 选题背景及意义 1.2国内外现状分析 1.3论文结构与章节安排 2 在线学习平台系统分析 2.1 可行性分析 2.2 系统业务流程分析 2.3 系统功能分析 2.3.1 功能性分析 2.3.2 非功能性分析 2.4 系统用例分析 2.5本章小结 3 在线学习平台总体设计 …...

【Linux 内核源码分析】内存映射(mmap)机制原理
内存映射(mmap)是 Linux 内核的一个重要机制,它为程序提供了一种将文件内容直接映射到进程虚拟地址空间的方式。同时内存映射也是虚拟内存管理和文件 IO 的重要组成部分。 在 Linux 中,虚拟内存管理是基于内存映射来实现的。在调用 mmap 函数时…...

贪心算法之合并区间
“任世界多宽广,停泊在这港口~” 区间问题,涉及到最多的就是 取交集 和 并集的概念。我们使用C排序算法后,其默认规则就是按照 “左排序”进行的。因而,我们实质上注意的是每一个区间的 右端点,根据题目要求ÿ…...

Eclipse - Colors and Fonts
Eclipse - Colors and Fonts References 编码最好使用等宽字体,Ubuntu 下自带的 Ubuntu Mono 可以使用。更换字体时看到名字里面带有 Mono 的基本都是等宽字体。 Window -> Preferences -> General -> Appearance -> Colors and Fonts -> C/C ->…...

java 数据结构LinkedList类
目录 什么是LinkedList 链表的概念及结构 链表的结构 无头单向非循环链表 addFirst方法(头插法) addLast方法(尾插法) addIndex方法 contains方法 removeAllKey方法 size和clear方法 链表oj题 无头双向非循环链表 ad…...

第五次作业(防御安全)
需求: 1.办公区设备可以通过电信链路和移动链路上网(多对多的NAT,并且需要保留一个公网IP 不能用来转换) 2.分公司设备可以通过总公司的移动链路和电信链路访问到DMZ区的http服务器 3.分公司内部的客户端可以通过公网地址访问到内部的服务…...