当前位置: 首页 > news >正文

[Spring Boot]登录密码三种加密方式

简述

介绍其三种密码加密方法
1.SM2加密与验签
2.随机密码盐加密
3.MD5加密
推荐使用方法1,其次使用方法2,最不推荐的是方法3。方法3极其容易被密码字典破解,如果项目进行安全测试,通常是不允许的加密方式。

SM2加密与验签

引入bcprov,以使用SM2加密。

        <dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15to18</artifactId><version>1.69</version></dependency>

工具类与测试方法

加密的主要工具类如下,其中带有测试的main方法。

import lombok.extern.slf4j.Slf4j;
import org.bouncycastle.asn1.gm.GMObjectIdentifiers;
import org.bouncycastle.crypto.InvalidCipherTextException;
import org.bouncycastle.crypto.engines.SM2Engine;
import org.bouncycastle.crypto.params.ECDomainParameters;
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.crypto.params.ParametersWithRandom;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPrivateKey;
import org.bouncycastle.jcajce.provider.asymmetric.ec.BCECPublicKey;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.jce.spec.ECParameterSpec;import java.security.*;
import java.security.spec.ECGenParameterSpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;
import java.util.Map;/*** sm2算法与签名的使用** @author fir* @date 2024/7/23 14:22*/
@Slf4j
public class Sm2SignatureUtils {static {Security.addProvider(new BouncyCastleProvider());}public static final String PUBLIC_KEY = "publicKey";public static final String PRIVATE_KEY = "privateKey";/*** 生成国密公私钥对*/public static Map<String, String> generateSmKey() throws Exception {KeyPairGenerator keyPairGenerator;SecureRandom secureRandom = new SecureRandom();ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");keyPairGenerator = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());keyPairGenerator.initialize(sm2Spec);keyPairGenerator.initialize(sm2Spec, secureRandom);KeyPair keyPair = keyPairGenerator.generateKeyPair();PrivateKey privateKey = keyPair.getPrivate();PublicKey publicKey = keyPair.getPublic();String publicKeyStr = new String(Base64.getEncoder().encode(publicKey.getEncoded()));String privateKeyStr = new String(Base64.getEncoder().encode(privateKey.getEncoded()));return Map.of(PUBLIC_KEY, publicKeyStr, PRIVATE_KEY, privateKeyStr);}/*** 将Base64转码的公钥串,转化为公钥对象*/public static PublicKey createPublicKey(String publicKey) {PublicKey publickey = null;try {X509EncodedKeySpec publicKeySpec = new X509EncodedKeySpec(Base64.getDecoder().decode(publicKey));KeyFactory keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider());publickey = keyFactory.generatePublic(publicKeySpec);} catch (Exception e) {log.error("将Base64转码的公钥串,转化为公钥对象异常:{}", e.getMessage(), e);}return publickey;}/*** 将Base64转码的私钥串,转化为私钥对象*/public static PrivateKey createPrivateKey(String privateKey) {PrivateKey publickey = null;try {PKCS8EncodedKeySpec pkcs8EncodedKeySpec = new PKCS8EncodedKeySpec(Base64.getDecoder().decode(privateKey));KeyFactory keyFactory = KeyFactory.getInstance("EC", new BouncyCastleProvider());publickey = keyFactory.generatePrivate(pkcs8EncodedKeySpec);} catch (Exception e) {log.error("将Base64转码的私钥串,转化为私钥对象异常:{}", e.getMessage(), e);}return publickey;}/*** 根据publicKey对原始数据data,使用SM2加密*/public static String encrypt(byte[] data, String publicKeyBase64) {PublicKey publicKey = createPublicKey(publicKeyBase64);ECPublicKeyParameters localEcPublicKeyParameters = getEcPublicKeyParameters(publicKey);SM2Engine localSm2Engine = new SM2Engine();localSm2Engine.init(true, new ParametersWithRandom(localEcPublicKeyParameters, new SecureRandom()));byte[] arrayOfByte2;try {arrayOfByte2 = localSm2Engine.processBlock(data, 0, data.length);return Base64.getEncoder().encodeToString(arrayOfByte2);} catch (InvalidCipherTextException e) {log.error("SM2加密失败:{}", e.getMessage(), e);return null;}}private static ECPublicKeyParameters getEcPublicKeyParameters(PublicKey publicKey) {ECPublicKeyParameters localEcPublicKeyParameters = null;if (publicKey instanceof BCECPublicKey localEcPublicKey) {ECParameterSpec localEcParameterSpec = localEcPublicKey.getParameters();ECDomainParameters localEcDomainParameters = new ECDomainParameters(localEcParameterSpec.getCurve(),localEcParameterSpec.getG(), localEcParameterSpec.getN());localEcPublicKeyParameters = new ECPublicKeyParameters(localEcPublicKey.getQ(), localEcDomainParameters);}return localEcPublicKeyParameters;}/*** 根据privateKey对加密数据encode data,使用SM2解密*/public static String decrypt(String encodeBase64, String privateKeyBase64) {SM2Engine localSm2Engine = new SM2Engine();PrivateKey privateKey = createPrivateKey(privateKeyBase64);BCECPrivateKey sm2PriK = (BCECPrivateKey) privateKey;byte[] encodeData = Base64.getDecoder().decode(encodeBase64);ECParameterSpec localEcParameterSpec = sm2PriK.getParameters();ECDomainParameters localEcDomainParameters = new ECDomainParameters(localEcParameterSpec.getCurve(),localEcParameterSpec.getG(), localEcParameterSpec.getN());ECPrivateKeyParameters localEcPrivateKeyParameters = new ECPrivateKeyParameters(sm2PriK.getD(),localEcDomainParameters);localSm2Engine.init(false, localEcPrivateKeyParameters);try {byte[] result = localSm2Engine.processBlock(encodeData, 0, encodeData.length);return new String(result);} catch (InvalidCipherTextException e) {log.error("SM2解密失败:{}", e.getMessage(), e);return null;}}/*** 私钥,数据,生成签名*/public static String signByPrivateKey(String dataStr, String privateKeyBase64) throws Exception {PrivateKey privateKey = createPrivateKey(privateKeyBase64);byte[] data = Base64.getDecoder().decode(dataStr);Signature sig = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);sig.initSign(privateKey);sig.update(data);byte[] sign = sig.sign();return Base64.getEncoder().encodeToString(sign);}/*** 公钥与签名验证数据合法性*/public static boolean verifyByPublicKey(String dataStr, String publicKeyBase64, String signatureBase64) throws Exception {PublicKey publicKey = createPublicKey(publicKeyBase64);byte[] signature = Base64.getDecoder().decode(signatureBase64);byte[] data = Base64.getDecoder().decode(dataStr);Signature sig = Signature.getInstance(GMObjectIdentifiers.sm2sign_with_sm3.toString(), BouncyCastleProvider.PROVIDER_NAME);sig.initVerify(publicKey);sig.update(data);return sig.verify(signature);}public static void test() throws Exception {// 生成公私钥对Map<String, String> keys = generateSmKey();String publicKey = keys.get(PUBLIC_KEY);String privateKey = keys.get(PRIVATE_KEY);String testStr = "123456";System.out.println("原始字符串:" + testStr);System.out.println("公钥:" + keys.get(PUBLIC_KEY));System.out.println("私钥:" + keys.get(PRIVATE_KEY));System.out.println();// 公钥加密String encrypt = encrypt(testStr.getBytes(), publicKey);System.out.println("加密数据:" + encrypt);// 私钥签名,后续根据数据与公钥验签String sign = signByPrivateKey(encrypt, privateKey);System.out.println("数据签名:" + sign);// 公钥验签,验证通过后再进行数据解密boolean b = verifyByPublicKey(encrypt, publicKey, sign);System.out.println("数据验签:" + b);//私钥解密String decrypt = decrypt(encrypt, privateKey);System.out.println("解密数据:" + decrypt);}public static void uesCase() throws Exception {//生成公私钥对String publicKey = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEsrdE0XrAO2S7Ize0tm0r3diH9cPH23t0J9yVDtiVux6g71msH5YGTWW6/ogQSCVJ4iaofgCS/ly5+wkXa+/IGg==";String privateKey = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgNxb+Jcu1vhGt9UEbeFUYeCC+RWL7+sfUL1vnhBp2KtKgCgYIKoEcz1UBgi2hRANCAASyt0TResA7ZLsjN7S2bSvd2If1w8fbe3Qn3JUO2JW7HqDvWawflgZNZbr+iBBIJUniJqh+AJL+XLn7CRdr78ga";String testStr = "123456";System.out.println("原始字符串:" + testStr);System.out.println("公钥:" + publicKey);System.out.println("私钥:" + privateKey);System.out.println();//公钥加密String encrypt = encrypt(testStr.getBytes(), publicKey);System.out.println("加密数据:" + encrypt);// 私钥签名,后续根据数据与公钥验签String sign = signByPrivateKey(encrypt, privateKey);System.out.println("数据签名:" + sign);//公钥验签,验证通过后再进行数据解密boolean b = verifyByPublicKey(encrypt, publicKey, sign);System.out.println("数据验签:" + b);//私钥解密String decrypt = decrypt(encrypt, privateKey);System.out.println("解密数据:" + decrypt);}public static void main(String[] args) {try {test();
//            uesCase();} catch (Exception e) {throw new RuntimeException(e);}}
}

使用案例

验证密码

接受到用户输入的用户与密码之后,在数据库中查询出旧的密码,并进行旧密码进行验签、解密。解密后判断用户输入的密码与数据库存储的密码是否相同。

        // 验证密码是否正确String password = "123456";String passwordOld = user.getPassword();String signature = user.getSignature();String decryptPasswordOld = null;try {// 公钥验签,查看数据与签名是否有效boolean b = Sm2SignatureUtils.verifyByPublicKey(passwordOld, public, signature);if(!b){throw new CommonException("数据损坏");}decryptPasswordOld = Sm2SignatureUtils.decrypt(passwordOld, private);}catch (Exception e){throw new CommonException("数据损坏");}if (decryptPasswordOld == null || !decryptPasswordOld.equals(password)) {throw new CommonException("用户密码错误");}
修改密码

接收到用户的密码后,根据公私要生成加密数据串与私钥签名。并存储到数据库,用于之后的密码验证。

            // 公钥加密String password = "123456";String encrypt = Sm2SignatureUtils.encrypt(password.getBytes(), public);// 根据数据与私钥,生成私钥签名String sign = Sm2SignatureUtils.signByPrivateKey(encrypt, private);user.setPassword(encrypt);user.setSignature(sign);

随机密码盐加密

工具类与测试方法

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.util.Base64;/*** @author fir* @date 2024/7/25 12:22*/
public class SaltUtils {/*** 生成随机安全盐** @return 盐*/public static String generateSalt() {// 使用SecureRandom生成安全的随机盐SecureRandom random = new SecureRandom();byte[] salt = new byte[16];random.nextBytes(salt);return Base64.getEncoder().encodeToString(salt);}/*** 生成加盐密码** @return 盐*/public static String hashPassword(String password, String salt){// 将密码和盐结合String saltedPassword = password + salt;// 使用SHA-256进行哈希MessageDigest md;try {md = MessageDigest.getInstance("SHA-256");}catch (NoSuchAlgorithmException e){throw new RuntimeException("加密盐处理失败");}byte[] hashedBytes = md.digest(saltedPassword.getBytes());// 将哈希值转换为字符串return Base64.getEncoder().encodeToString(hashedBytes);}public static void main(String[] args){String salt = generateSalt();String password = "123456";String hashPassword = hashPassword(password, salt);System.out.println("盐:" + salt);System.out.println("密码:" + password);System.out.println("加密密码:" + hashPassword);}}

使用案例

验证密码

查询出用户的密码,将用户输入的密码盐加密,并判断与数据库的加密密码是否一致。

        String password = "123456";String salt = user.getSalt();String passwordOld = user.getPassword();String mPassword = SaltUtils.hashPassword(password, salt);if (!mPassword.equals(passwordOld)) {throw new CommonException("密码错误");}
修改密码

将用户输入的密码md5加密之后,存在数据库中,用于之后的密码验证

        String password = "123456";String salt = SaltUtils.generateSalt();String hashPassword = SaltUtils.hashPassword(password, salt);user.setPassword(hashPassword);

MD5加密

引入hutool包,以使用md5加密。

        <dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.19</version></dependency>

测试方法

import cn.hutool.crypto.digest.MD5;/*** @author fir* @date 2024/7/22 10:07*/
public class Md5Utils {public static void main(String[] args){// MD5取值String mPassword = MD5.create().digestHex("123456");System.out.println(mPassword);}
}

使用案例

验证密码

查询出用户的密码,将用户输入的密码MD5加密,并判断与数据库的加密密码是否一致。

        String password = "123456";String mPassword = MD5.create().digestHex(password);String passwordOld = user.getPassword();if (!mPassword.equals(passwordOld)) {throw new CommonException("密码错误");}
修改密码

将用户输入的密码md5加密之后,存在数据库中,用于之后的密码验证

        String password = "123456";String passwordMd5 = MD5.create().digestHex(password);user.setPassword(passwordMd5);

相关文章:

[Spring Boot]登录密码三种加密方式

简述 介绍其三种密码加密方法 1.SM2加密与验签 2.随机密码盐加密 3.MD5加密 推荐使用方法1&#xff0c;其次使用方法2&#xff0c;最不推荐的是方法3。方法3极其容易被密码字典破解&#xff0c;如果项目进行安全测试&#xff0c;通常是不允许的加密方式。 SM2加密与验签 引入…...

前端面试项目细节重难点分享(十三)

面试题提问&#xff1a;分享你最近做的这个项目&#xff0c;并讲讲该项目的重难点&#xff1f; 答&#xff1a;最近这个项目是一个二次迭代开发项目&#xff0c;迭代周期一年&#xff0c;在做这些任务需求时&#xff0c;确实有很多值得分享的印象深刻的点&#xff0c;我讲讲下面…...

每天五分钟深度学习:向量化方式完成逻辑回归m个样本的前向传播

本文重点 我们已经知道了向量化可以明显的加速程序的运行速度,本节课程将使用向量化来完成逻辑回归的前向传播,不使用一个for循环。 逻辑回归的前向传播 我们先来回忆一下逻辑回归的前向传播,如果我们有m个训练样本,首先对第一个样本进行预测,我们需要计算z,然后计算预…...

以线程完成并发的UDP服务端

网络(九)并发的UDP服务端 以线程完成功能 客户端 // todo UDP发送端 #include <stdio.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <sys/types.h> #include <stdlib.h> #include <string.h…...

linux c 特殊字符分割

/* * brief: 根据split_symbol分割字符串 * param: str为要分割的字符串&#xff0c;split_symbol是分隔符 * return&#xff1a;返回garray的指针数组&#xff0c;如果返回非空需要自己处理释放 */ GPtrArray_autoptr char_sz_spilt(pchar* str, pchar split_symbol) {if (NUL…...

搭建本地私有知识问答系统:MaxKB + Ollama + Llama3 (wsl网络代理配置、MaxKB-API访问配置)

目录 搭建本地私有知识问答系统:MaxKB、Ollama 和 Llama3 实现指南引言MaxKB+Ollama+Llama 3 Start buildingMaxKB 简介:1.1、docker部署 MaxKB(方法一)1.1.1、启用wls或是开启Hyper使用 WSL 2 的优势1.1.2、安装docker1.1.3、docker部署 MaxKB (Max Knowledge Base)MaxKB …...

谷粒商城实战笔记-65-商品服务-API-品牌管理-表单校验自定义校验器

文章目录 1&#xff0c;el-form品牌logo图片自定义显示2&#xff0c;重新导入和注册element-ui组件3&#xff0c;修改brand-add-or-update.vue控件的表单校验规则firstLetter 校验规则sort 校验规则 1&#xff0c;el-form品牌logo图片自定义显示 为了在品牌列表中自定义显示品…...

学好C++之——命名空间

c开始学习之时&#xff0c;你不可避免会遇到一个新朋友&#xff0c;那就是——namespace&#xff08;命名空间&#xff09;。 那么这篇文章就来为你解决这个小麻烦喽~ 目录 1.namespace存在的意义 2.namespace的定义 3.namespace的使用 1.namespace存在的意义 在C中&#…...

pytorch lightning报错all tensors to be on the same device

RuntimeError: Expected all tensors to be on the same device, but found at least two devices, cuda:0 and cpu! 修改指定为gpu trainer pl.Trainer(max_epochstrain_params.iterations, loggertb_logger,acceleratorgpu, devices1)...

Redis中的哨兵(Sentinel)

上篇文章我们讲述了Redis中的主从复制&#xff08;Redis分布式系统中的主从复制-CSDN博客&#xff09;&#xff0c;本篇文章针对主从复制中的问题引出Redis中的哨兵&#xff0c;希望本篇文章会对你有所帮助。 文章目录 一、引入哨兵机制 二、基本概念 三、主从复制的问题 四、哨…...

产业创新研究杂志产业创新研究杂志社产业创新研究编辑部2024年第12期目录

高质量发展 如何在新一轮产业链变革中平稳应对挑战 王宏利; 1-3《产业创新研究》投稿&#xff1a;cnqikantg126.com 基于ERGM的城市间绿色低碳技术专利转让网络结构及演化研究 吕彦朋;姜军;张宁; 4-6 数字基础设施建设对城市FDI的影响——基于“宽带中国”试点政策…...

网闸(Network Gatekeeper或Security Gateway)

本心、输入输出、结果 文章目录 网闸(Network Gatekeeper或Security Gateway)前言网闸主要功能网闸工作原理网闸使用场景网闸网闸(Network Gatekeeper或Security Gateway) 编辑 | 简简单单 Online zuozuo 地址 | https://blog.csdn.net/qq_15071263 如果觉得本文对你有帮助…...

C#中的字符串

String 在实例方法中string虽然传入的是引用类型 但是修改string 并不是修改原来堆里面的值 而是又重新创建一个堆值 用来然后用方法内的变量指向新的堆值 C# 中的字符串&#xff08;string 类型&#xff09;提供了许多有用的方法来处理字符串数据。以下是一些常用的字符…...

docker安装部署elasticsearch7.15.2

docker安装部署elasticsearch7.15.2 1.拉取es镜像 docker pull docker.elastic.co/elasticsearch/elasticsearch:7.15.2如果不想下载或者镜像拉去太慢可以直接下载文章上面的镜像压缩包 使用镜像解压命令 docker load -i elasticsearch-7-15-2.tar如下图所示就表示镜像解压成…...

Symfony 入门指南:快速安装与基础配置

Symfony 入门指南&#xff1a;快速安装与基础配置 Symfony 是一个强大而灵活的 PHP 框架&#xff0c;广泛应用于构建现代 Web 应用程序。本指南将带您一步一步地了解如何快速安装 Symfony&#xff0c;并完成基本配置&#xff0c;以便您能够开始使用这个强大的框架。 目录 引…...

3.3V升压至5V的AH6922芯片:高效能的SOP8封装解决方案

# 3.3V升压至5V的AH6922芯片&#xff1a;高效能的SOP8封装解决方案 在当今快速发展的电子设备领域&#xff0c;对于电源管理的需求日益增长。特别是对于便携式产品和手持设备&#xff0c;一个高效、稳定且体积小巧的升压解决方案变得至关重要。本文将介绍一款专为这些需求设计…...

赋能未来教育,3DCAT助力深圳鹏程技师学院打造5G+XR实训室

随着国家对教育行业的重视&#xff0c;实训室建设已成为推动教育现代化的关键。《教育信息化2.0行动计划》、《职业教育示范性虚拟仿真实训基地建设指南》等政策文件&#xff0c;明确指出了加强虚拟仿真实训教学环境建设的重要性。 在这一大背景下&#xff0c;教育行业对于实训…...

力扣141环形链表问题|快慢指针算法详细推理,判断链表是否有环|龟兔赛跑算法

做题链接 目录 前言&#xff1a; 一、算法推导&#xff1a; 1.假设有环并且一定会相遇&#xff0c;那么一定是在环内相遇&#xff0c;且是快指针追上慢指针。 2.有环就一定会相遇吗&#xff1f;快指针是每次跳两步&#xff0c;有没有可能把慢指针跳过去&#xff1f; 3.那一定…...

React 常见的报错及解决方法

1、Warning: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons&#xff08;无效的钩子调用。钩子只能在函数组件的内部调用。这可能是由于以下原因之一&#xff09; 原因&#x…...

更新服务器nginx 1.26.1版本

今天在官网下载了nginx1的1.26.1版本&#xff0c;使用gpt的脚本想直接覆盖安装&#xff0c;脚本如下 #!/bin/bash# 设置变量 NGINX_VERSION"1.26.1" TAR_FILE"nginx-$NGINX_VERSION.tar.gz" SRC_DIR"nginx-$NGINX_VERSION"# 检查是否存在tar包 …...

AI-调查研究-01-正念冥想有用吗?对健康的影响及科学指南

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; &#x1f680; AI篇持续更新中&#xff01;&#xff08;长期更新&#xff09; 目前2025年06月05日更新到&#xff1a; AI炼丹日志-28 - Aud…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。

1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj&#xff0c;再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...

使用 SymPy 进行向量和矩阵的高级操作

在科学计算和工程领域&#xff0c;向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能&#xff0c;能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作&#xff0c;并通过具体…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...