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

三步实现Java的SM2前端加密后端解密

秦医如毒,无药可解。

话不多说,先上需要用到的js文件下载链接  和  jsp前端代码

第一步:下载两个必备的js文件—— crypto-js.jssm2.js 

它们的下载链接如下↓(该网页不魔法上网的话会很卡,毕竟github,建议卡的话就多重新加载几次,我差不多试了8次才进去):

https://github.com/Saberization/SM2

进入网页,下载后拿取下方↓图片上的两个js就行:

然后,将这两js放到存放静态资源(static)的目录下,我放的是static中的sm2目录(sm2这个目录是我创的)

后面,在jsp的<head></head>中引入这两个js文件

<!--jsp引入sm2,实现前端加密-->
<script type="text/javascript" src="${pageContext.request.contextPath}/static/sm2/crypto-js.js" charset="utf-8"></script>
<script type="text/javascript" src="${pageContext.request.contextPath}/static/sm2/sm2.js" charset="utf-8"></script>
第二步前端jsp代码实现,下方的代码写在jsp页面的<script type="text/javascript"></script>中。

作用是,当调用下方↓函数的时候,会给你传入的值进行加密并返回。

注:【你生成的公钥】的生成方式可以在文章末尾的SM2Utils.java工具类中可以找到,是个main方法,一键生成,简单粗暴

<!--sm2加密函数-->
function sm2EncryptPwd(data) {<!--sm2公钥-->var publicKey = '你生成的公钥';return sm2Encrypt(data, publicKey, 1);
}

至此,前端加密结束,进入后端解密环节——

后端需要的jar包是:bcprov-jdk15on-1.68.jar

注意!!!该jar包必须要1.60版本以上,不然解密的时候会缺少必要的条件!!!并且我用的时候,本地环境是JDK1.8的,其他环境没试过,建议如有不同,先查一下。

<dependency><groupId>org.bouncycastle</groupId><artifactId>bcprov-jdk15on</artifactId><version>1.68</version>
</dependency>
第三步后端代码实现。

导入jar包后,就是必要的工具类实体类:SM2Utils.java

你可以用工具类本身的加密方法解密,也可以用工具类中我写的 getJieMiJieGuo() 方法解密。

我个人建议用我写的,因为操作起来更简单些,只需要传入加密后的字符串,就可以返回解密的数据。

其中【你生成的公钥】和【你生成的私钥】可以通过工具类中的方法生成,生成完复制粘贴进去就行

注!后端和前端的公钥要保持一致!因为公钥私钥是配对使用的!

package com.test.common.utils;import org.apache.commons.net.util.Base64;
import org.bouncycastle.asn1.gm.GMNamedCurves;
import org.bouncycastle.asn1.x9.X9ECParameters;
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 org.bouncycastle.jce.spec.ECPrivateKeySpec;
import org.bouncycastle.jce.spec.ECPublicKeySpec;
import org.bouncycastle.util.encoders.Hex;import java.math.BigInteger;
import java.security.*;
import java.security.spec.ECGenParameterSpec;public class SM2Utils {private static final String publicKey = "你生成的公钥";private static final String privateKey = "你生成私钥";/*** 解密,并且获取解密后的字符串** @return 秦无解*/public static String getJieMiJieGuo(String cipherData) {byte[] cipherDataByte = Hex.decode(cipherData);BigInteger privateKeyD = new BigInteger(privateKey, 16);X9ECParameters sm2ECParameters1 = GMNamedCurves.getByName("sm2p256v1");ECDomainParameters domainParameters1 = new ECDomainParameters(sm2ECParameters1.getCurve(), sm2ECParameters1.getG(), sm2ECParameters1.getN());ECPrivateKeyParameters privateKeyParameters = new ECPrivateKeyParameters(privateKeyD, domainParameters1);//用私钥解密,SM2Engine.Mode.C1C3C2得加,不然就会报错invalid cipher textSM2Engine sm2Engine = new SM2Engine(SM2Engine.Mode.C1C3C2);sm2Engine.init(false, privateKeyParameters);//processBlock得到Base64格式,记得解码byte[] arrayOfBytes = null;try {arrayOfBytes = Base64.decodeBase64(sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length));} catch (Exception e) {e.printStackTrace();return null;}//得到明文:SM2 Encryption Testreturn new String(arrayOfBytes);}/*** @Description 生成秘钥对* @Author msx* @return KeyPair*/public static KeyPair createECKeyPair() {//使用标准名称创建EC参数生成的参数规范final ECGenParameterSpec sm2Spec = new ECGenParameterSpec("sm2p256v1");// 获取一个椭圆曲线类型的密钥对生成器final KeyPairGenerator kpg;try {kpg = KeyPairGenerator.getInstance("EC", new BouncyCastleProvider());// 使用SM2算法域参数集初始化密钥生成器(默认使用以最高优先级安装的提供者的 SecureRandom 的实现作为随机源)// kpg.initialize(sm2Spec);// 使用SM2的算法域参数集和指定的随机源初始化密钥生成器kpg.initialize(sm2Spec, new SecureRandom());// 通过密钥生成器生成密钥对return kpg.generateKeyPair();} catch (Exception e) {e.printStackTrace();return null;}}/*** @Description 公钥加密* @Author msx* @param publicKeyHex SM2十六进制公钥* @param data         明文数据* @return String*/public static String encrypt1(String publicKeyHex, String data) {return encrypt(getECPublicKeyByPublicKeyHex(publicKeyHex), data, 1);}/*** @Description 公钥加密* @Author msx* @param data         明文数据* @return String*/public static String encrypt(String data) {return encrypt(getECPublicKeyByPublicKeyHex(publicKey), data, 1);}/*** @Description 公钥加密* @Author msx* @param publicKey SM2公钥* @param data      明文数据* @param modeType  加密模式* @return String*/public static String encrypt(BCECPublicKey publicKey, String data, int modeType) {//加密模式SM2Engine.Mode mode = SM2Engine.Mode.C1C3C2;if (modeType != 1) {mode = SM2Engine.Mode.C1C2C3;}//通过公钥对象获取公钥的基本域参数。ECParameterSpec ecParameterSpec = publicKey.getParameters();ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),ecParameterSpec.getG(), ecParameterSpec.getN());//通过公钥值和公钥基本参数创建公钥参数对象ECPublicKeyParameters ecPublicKeyParameters = new ECPublicKeyParameters(publicKey.getQ(), ecDomainParameters);//根据加密模式实例化SM2公钥加密引擎SM2Engine sm2Engine = new SM2Engine(mode);//初始化加密引擎sm2Engine.init(true, new ParametersWithRandom(ecPublicKeyParameters, new SecureRandom()));byte[] arrayOfBytes = null;try {//将明文字符串转换为指定编码的字节串byte[] in = data.getBytes("utf-8");//通过加密引擎对字节数串行加密arrayOfBytes = sm2Engine.processBlock(in, 0, in.length);} catch (Exception e) {System.out.println("SM2加密时出现异常:" + e.getMessage());e.printStackTrace();}//将加密后的字节串转换为十六进制字符串return Hex.toHexString(arrayOfBytes);}/*** @Description 私钥解密* @Author msx* @param privateKeyHex SM2十六进制私钥* @param cipherData    密文数据* @return String*/public static String decrypt1(String privateKeyHex, String cipherData) {return decrypt(getBCECPrivateKeyByPrivateKeyHex(privateKeyHex), cipherData, 1);}/*** @Description 私钥解密* @Author msx* @param s* @param cipherData    密文数据* @return String*/public static String decrypt(String s, String cipherData) {return decrypt(getBCECPrivateKeyByPrivateKeyHex(privateKey), cipherData, 1);}/*** @Description 私钥解密* @Author msx* @param privateKey SM私钥* @param cipherData 密文数据* @param modeType   解密模式* @return*/public static String decrypt(BCECPrivateKey privateKey, String cipherData, int modeType) {//解密模式SM2Engine.Mode mode = SM2Engine.Mode.C1C3C2;if (modeType != 1) {mode = SM2Engine.Mode.C1C2C3;}//将十六进制字符串密文转换为字节数组(需要与加密一致,加密是:加密后的字节数组转换为了十六进制字符串)byte[] cipherDataByte = Hex.decode(cipherData);//通过私钥对象获取私钥的基本域参数。ECParameterSpec ecParameterSpec = privateKey.getParameters();ECDomainParameters ecDomainParameters = new ECDomainParameters(ecParameterSpec.getCurve(),ecParameterSpec.getG(), ecParameterSpec.getN());//通过私钥值和私钥钥基本参数创建私钥参数对象ECPrivateKeyParameters ecPrivateKeyParameters = new ECPrivateKeyParameters(privateKey.getD(),ecDomainParameters);//通过解密模式创建解密引擎并初始化SM2Engine sm2Engine = new SM2Engine(mode);sm2Engine.init(false, ecPrivateKeyParameters);String result = null;try {//通过解密引擎对密文字节串进行解密byte[] arrayOfBytes = sm2Engine.processBlock(cipherDataByte, 0, cipherDataByte.length);//将解密后的字节串转换为utf8字符编码的字符串(需要与明文加密时字符串转换成字节串所指定的字符编码保持一致)result = new String(arrayOfBytes, "utf-8");} catch (Exception e) {System.out.println("SM2解密时出现异常" + e.getMessage());}return result;}//椭圆曲线ECParameters ASN.1 结构private static X9ECParameters x9ECParameters = GMNamedCurves.getByName("sm2p256v1");//椭圆曲线公钥或私钥的基本域参数。private static ECParameterSpec ecDomainParameters = new ECParameterSpec(x9ECParameters.getCurve(), x9ECParameters.getG(), x9ECParameters.getN());/*** @Description 公钥字符串转换为 BCECPublicKey 公钥对象* @Author msx* @param pubKeyHex 64字节十六进制公钥字符串(如果公钥字符串为65字节首个字节为0x04:表示该公钥为非压缩格式,操作时需要删除)* @return BCECPublicKey SM2公钥对象*/public static BCECPublicKey getECPublicKeyByPublicKeyHex(String pubKeyHex) {//截取64字节有效的SM2公钥(如果公钥首个字节为0x04)if (pubKeyHex.length() > 128) {pubKeyHex = pubKeyHex.substring(pubKeyHex.length() - 128);}//将公钥拆分为x,y分量(各32字节)String stringX = pubKeyHex.substring(0, 64);String stringY = pubKeyHex.substring(stringX.length());//将公钥x、y分量转换为BigInteger类型BigInteger x = new BigInteger(stringX, 16);BigInteger y = new BigInteger(stringY, 16);//通过公钥x、y分量创建椭圆曲线公钥规范ECPublicKeySpec ecPublicKeySpec = new ECPublicKeySpec(x9ECParameters.getCurve().createPoint(x, y), ecDomainParameters);//通过椭圆曲线公钥规范,创建出椭圆曲线公钥对象(可用于SM2加密及验签)return new BCECPublicKey("EC", ecPublicKeySpec, BouncyCastleProvider.CONFIGURATION);}/*** @Description 私钥字符串转换为 BCECPrivateKey 私钥对象* @Author msx* @param privateKeyHex 32字节十六进制私钥字符串* @return BCECPrivateKey SM2私钥对象*/public static BCECPrivateKey getBCECPrivateKeyByPrivateKeyHex(String privateKeyHex) {//将十六进制私钥字符串转换为BigInteger对象BigInteger d = new BigInteger(privateKeyHex, 16);//通过私钥和私钥域参数集创建椭圆曲线私钥规范ECPrivateKeySpec ecPrivateKeySpec = new ECPrivateKeySpec(d, ecDomainParameters);//通过椭圆曲线私钥规范,创建出椭圆曲线私钥对象(可用于SM2解密和签名)return new BCECPrivateKey("EC", ecPrivateKeySpec, BouncyCastleProvider.CONFIGURATION);}public static void main(String[] args) {String publicKeyHex = null;String privateKeyHex = null;KeyPair keyPair = createECKeyPair();PublicKey publicKey = keyPair.getPublic();if (publicKey instanceof BCECPublicKey) {//获取65字节非压缩缩的十六进制公钥串(0x04)publicKeyHex = Hex.toHexString(((BCECPublicKey) publicKey).getQ().getEncoded(false));System.out.println("---->SM2公钥:" + publicKeyHex);}PrivateKey privateKey = keyPair.getPrivate();if (privateKey instanceof BCECPrivateKey) {//获取32字节十六进制私钥串privateKeyHex = ((BCECPrivateKey) privateKey).getD().toString(16);System.out.println("---->SM2私钥:" + privateKeyHex);}/*** 公钥加密*/String data = "=========待加密数据=========";//将十六进制公钥串转换为 BCECPublicKey 公钥对象String encryptData = encrypt1(publicKeyHex, data);System.out.println("---->加密结果:" + encryptData);/*** 私钥解密*///将十六进制私钥串转换为 BCECPrivateKey 私钥对象data = decrypt1(privateKeyHex, encryptData);System.out.println("---->解密结果:" + data);}
}

最后,在后端接口中调用工具类的解密方法,就可以对前端传来的加密数据进行解密。

至此,✿✿ヽ(°▽°)ノ✿撒花。

此章暂时完结。

相关文章:

三步实现Java的SM2前端加密后端解密

秦医如毒&#xff0c;无药可解。 话不多说&#xff0c;先上需要用到的js文件下载链接 和 jsp前端代码。 第一步&#xff1a;下载两个必备的js文件—— crypto-js.js、sm2.js 。 它们的下载链接如下↓&#xff08;该网页不魔法上网的话会很卡&#xff0c;毕竟github&#x…...

1分钟带你了解golang(go语言)

Golang&#xff1a;也被称为Go语言&#xff0c;是一种开源的编程语言。由Google的Robert Griesemer、Rob Pike和Ken Thompson于2007年开始设计&#xff0c;2009年11月正式对外发布。&#xff08;被誉为21世纪的C语言&#xff09; 像python一样的优雅&#xff0c;有c一样的性能…...

CSS-4

平面转换 整体认识 div {margin: 100px 0;width: 100px;height: 100px;background-color: pink;/* 过渡效果 */transition: all 1s;}/* 当鼠标悬停到div时&#xff0c;进行平面转换 */div:hover {transform: translate(800px) rotate(360deg) scale(2) skew(180deg);}作用&…...

Python为何适合开发AI项目?

Python在人工智能&#xff08;AI&#xff09;项目中的流行和广泛应用归因于多个因素&#xff0c;其中一些主要原因包括&#xff1a; 1、易学易用&#xff1a; Python语法简洁清晰&#xff0c;易于学习和理解。这使得新手能够更容易上手&#xff0c;并且对于处理复杂的AI算法和…...

总结心得:各设计模式使用场景

单例模式&#xff1a;创建单个对象 工厂模式&#xff1a;创建对象交给工厂完成&#xff0c;当需要创建的对象是一系列相互关联或相互依赖的产品族时 原型模式&#xff1a;克隆对象&#xff0c;避免创建初始化开销 建造者模式&#xff1a;创建一个复杂对象&#xff0c;该对象…...

详解Vue3中的事件监听方式

本文主要介绍Vue3中的事件监听方式。 目录 一、v-on指令二、使用符号简写三、事件修饰符四、动态事件名五、常见的监听事件六、自定义事件 在Vue3中&#xff0c;事件监听的方式与Vue2有一些不同。 下面是Vue3中事件监听方式的详细介绍&#xff1a; 一、v-on指令 Vue3中仍然使…...

Unity关于easySave2 easySave3保存数据的操作;包含EasySave3运行报错的解决

关于easySave2 easySave3保存数据的操作&#xff1b;包含EasySave3运行报错的解决 /// 数据存储路径&#xff08;Easy Save的默认储存位置为&#xff1a;Application.persistentDataPath&#xff0c;为了方便我们可以给它指定储存路径&#xff09; #region 存储数据/*/// /// 存…...

2022年全球软件质量效能大会(QECon上海站)-核心PPT资料下载

一、峰会简介 近年来&#xff0c;以云计算、移动互联网、物联网、工业互联网、人工智能、大数据及区块链等新一代信息技术构建的智能化应用和产品出现爆发式增长&#xff0c;突破了对于软件形态的传统认知&#xff0c;正以各种展现方式诠释着对新型智能软件的定义。这也使得对…...

【python报错】UserWarning: train_labels has been renamed targets

UserWarning: train_labels has been renamed targetswarnings.warn(“train_labels has been renamed targets”) 这是一条 Python 警告信息&#xff0c;它表示 train_labels 这个变量已经被重命名为 targets&#xff0c;在将来的版本中可能会移除 train_labels。因此&#x…...

算法专题四:前缀和

前缀和 一.一维前缀和(模板)&#xff1a;1.思路一&#xff1a;暴力解法2.思路二&#xff1a;前缀和思路 二. 二维前缀和(模板)&#xff1a;1.思路一&#xff1a;构造前缀和数组 三.寻找数组的中心下标&#xff1a;1.思路一&#xff1a;前缀和 四.除自身以外数组的乘积&#xff…...

STM32学习笔记十五:WS2812制作像素游戏屏-飞行射击游戏(5)探索动画之帧动画

本章又是个重要的章节——动画。 动画&#xff0c;本质上时一系列静态的画面连续播放&#xff0c;欺骗人眼产生动画效果。这个原理自打十九世纪电影诞生开始&#xff0c;就从来没变过。 我们的游戏中也需要一些动画效果&#xff0c;比如&#xff0c;被击中时的受伤效果&#…...

期末复习(程序设计)

根据字符出现频率排序 【问题描述】 给定一个字符串 s &#xff0c;根据字符出现的 频率 对其进行降序排序。一个字符出现的频率是它出现在字符串中的次数。 返回已排序的字符串。 频率相同的的字符按ascii值降序排序。 s不包含空格、制表符、换行符等特殊字符。 【输入格…...

html-css-js移动端导航栏底部固定+i18n国际化全局

需求&#xff1a;要做一个移动端的仿照小程序的导航栏页面操作&#xff0c;但是这边加上了i18n国家化&#xff0c;由于页面切换的时候会导致国际化失效&#xff0c;所以写了这篇文章 1.效果 切换页面的时候中英文也会跟着改变&#xff0c;不会导致切换后回到默认的语言 2.实现…...

Ubuntu Linux 入门指南:面向初学者

目录 1. Ubuntu Linux 简介 Ubuntu 的由来 Ubuntu 与其他 Linux 发行版的比较 Debian&#xff1a; Fedora&#xff1a; openSUSE&#xff1a; Arch Linux&#xff1a; Linux Mint&#xff1a; 第二部分&#xff1a;安装 Ubuntu 1. 准备安装 系统需求 创建 Ubuntu 启…...

常见算法面试题目

前言 总结一些常见的算法题目&#xff0c;每一个题目写一行思路&#xff0c;方便大家复习。具体题目的来源是下面的网站。 剑指offer 剑指offe2 leetcode200题 leetcode 100题 leetcode150题 leetcode 75题 文章目录 前言二叉树非递归遍历牛客JZ31 栈的压入、弹出序列 (…...

PiflowX组件-JDBCWrite

JDBCWrite组件 组件说明 使用JDBC驱动向任意类型的关系型数据库写入数据。 计算引擎 flink 有界性 Sink: Batch Sink: Streaming Append & Upsert Mode 组件分组 Jdbc 端口 Inport&#xff1a;默认端口 outport&#xff1a;默认端口 组件属性 名称展示名称默…...

算法导论复习题目

这题需要考虑什么呢&#xff1f; 一换元&#xff0c;二要使用主方法猜出结果&#xff0c;三是证明的时候添加一个低阶项来消除 LC检索 C&#xff08;x&#xff09;是从上帝视角来看的成本 对C(x)的一个估计&#xff1a; 由两个部分组成&#xff0c;就相当于由以往的经验对未来…...

HTTPS协议详解

目录 前言 一、HTTPS协议 1、加密是什么 2、为什么要加密 二、常见加密方式 1、对称加密 2、非对称加密 三、数据摘要与数据指纹 1、数据摘要 2、数据指纹 四、HTTPS加密策略探究 1、只使用对称加密 2、只使用非对称加密 3、双方都使用非对称加密 4、对称加密非…...

菜鸟学习vue3笔记-vue3 router回顾

1、路由router pnpm i vue-router2、创建使用环境 1.src下创建 router文件夹、里面创建index.ts文件 //创建一个路由暴露出去//1.引入createRouter import { createRouter, createWebHistory } from "vue-router";// import Home from ../components/Home.vue//…...

Mybatis枚举类型处理和类型处理器

专栏精选 引入Mybatis Mybatis的快速入门 Mybatis的增删改查扩展功能说明 mapper映射的参数和结果 Mybatis复杂类型的结果映射 Mybatis基于注解的结果映射 Mybatis枚举类型处理和类型处理器 再谈动态SQL Mybatis配置入门 Mybatis行为配置之Ⅰ—缓存 Mybatis行为配置…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

C++ 基础特性深度解析

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

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)

前言&#xff1a; 最近在做行为检测相关的模型&#xff0c;用的是时空图卷积网络&#xff08;STGCN&#xff09;&#xff0c;但原有kinetic-400数据集数据质量较低&#xff0c;需要进行细粒度的标注&#xff0c;同时粗略搜了下已有开源工具基本都集中于图像分割这块&#xff0c…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)

RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发&#xff0c;后来由Pivotal Software Inc.&#xff08;现为VMware子公司&#xff09;接管。RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;用 Erlang 语言编写。广泛应用于各种分布…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官

。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量&#xff1a;setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

android RelativeLayout布局

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"android:gravity&…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...