Google验证码,扫描绑定,SpringBoot+ vue

文章目录

    • 后端
      • 1.使用Google工具类
      • 这个 类的 verifyTest 方法可以判断扫描绑定之后的app上面验证码的准确性。
      • 这个类通过g_user,g_code(就是谷歌验证器的secret,这个你已经插入到数据库 中)来生成相关二维码。
      • 2.用工具类自带的g_user,g_code来生成二维码
      • 2.1通过请求来生成相关二维码,后端返回给前端
      • 3.第一次通过生成的secret_key登录,之后扫描进行绑定Google验证码,通过验证码进行登录
    • 前端Vue

后端

1.使用Google工具类

package com.ruoyi.common.utils.googleAuth;
import org.apache.commons.codec.binary.Base32;
import org.apache.commons.codec.binary.Base64;import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;public class GoogleGenerator {// 生成的key长度( Generate secret key length)public static final int SECRET_SIZE = 10;public static final String SEED = "22150146801713967E8g";// Java实现随机数算法public static final String RANDOM_NUMBER_ALGORITHM = "SHA1PRNG";// 最多可偏移的时间int window_size = 3; // default 3 - max 17public static String generateSecretKey() {SecureRandom sr;try {sr = SecureRandom.getInstance(RANDOM_NUMBER_ALGORITHM);sr.setSeed(Base64.decodeBase64(SEED));byte[] buffer = sr.generateSeed(SECRET_SIZE);Base32 codec = new Base32();byte[] bEncodedKey = codec.encode(buffer);return new String(bEncodedKey);} catch (NoSuchAlgorithmException e) {e.printStackTrace();}return null;}/*** 这个format不可以修改,身份验证器无法识别二维码*/public static String getQRBarcode(String user, String secret) {String format = "otpauth://totp/%s?secret=%s";return String.format(format, user, secret);}/*** 根据user和secret生成二维码的密钥*/public static String getQRBarcodeURL(String user, String host, String secret) {String format = "http://www.google.com/chart?chs=200x200&chld=M%%7C0&cht=qr&chl=otpauth://totp/%s@%s?secret=%s";return String.format(format, user, host, secret);}public boolean check_code(String secret, String code, long timeMsec) {Base32 codec = new Base32();byte[] decodedKey = codec.decode(secret);long t = (timeMsec / 1000L) / 30L;for (int i = -window_size; i <= window_size; ++i) {long hash;try {hash = verify_code(decodedKey, t + i);} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e.getMessage());}System.out.println("code=" + code);System.out.println("hash=" + hash);if (code.equals(addZero(hash))) {return true;}}return false;}private static int verify_code(byte[] key, long t) throws NoSuchAlgorithmException, InvalidKeyException {byte[] data = new byte[8];long value = t;for (int i = 8; i-- > 0; value >>>= 8) {data[i] = (byte) value;}SecretKeySpec signKey = new SecretKeySpec(key, "HmacSHA1");Mac mac = Mac.getInstance("HmacSHA1");mac.init(signKey);byte[] hash = mac.doFinal(data);int offset = hash[20 - 1] & 0xF;long truncatedHash = 0;for (int i = 0; i < 4; ++i) {truncatedHash <<= 8;truncatedHash |= (hash[offset + i] & 0xFF);}truncatedHash &= 0x7FFFFFFF;truncatedHash %= 1000000;return (int) truncatedHash;}private String addZero(long code) {return String.format("%06d", code);}
}

这个 类的 verifyTest 方法可以判断扫描绑定之后的app上面验证码的准确性。

package com.ruoyi.common.utils.googleAuth;/***** 身份认证测试** @author yangbo** @version 创建时间:2017年8月14日 上午11:09:23***/
public class GoogleUtils {//@Testpublic String genSecret(String g_name) {// 生成密钥String secret = GoogleGenerator.generateSecretKey();// 把这个qrcode生成二维码,用google身份验证器扫描二维码就能添加成功String qrcode = GoogleGenerator.getQRBarcode(g_name, secret);System.out.println("qrcode:" + qrcode + ",key:" + secret);return secret;}/*** 对app的随机生成的code,输入并验证*/public static boolean verifyTest(String code,String secret) {long t = System.currentTimeMillis();GoogleGenerator ga = new GoogleGenerator();// ga.setWindowSize(5);boolean r = ga.check_code(secret, code, t);System.out.println("检查code是否正确?" + r);return r;}public static void main(String [] args){GoogleUtils gt=new GoogleUtils();String secret=gt.genSecret("Antpay(web3game)");verifyTest("Antpay(web3game)","2DYHBGQLNLQWSPZV");}
}

这个类通过g_user,g_code(就是谷歌验证器的secret,这个你已经插入到数据库 中)来生成相关二维码。

package com.ruoyi.common.utils.googleAuth;import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;import java.util.HashMap;
import java.util.Map;/*** 二维码工具类*/
public class QRCodeUtil {/*** 生成二维码** @param content 二维码的内容* @return BitMatrix对象*/public static BitMatrix createCode(String content) {//二维码的宽高int width = 200;int height = 200;//其他参数,如字符集编码Map<EncodeHintType, Object> hints = new HashMap<>();hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");//容错级别为Hhints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);//白边的宽度,可取0~4hints.put(EncodeHintType.MARGIN, 0);BitMatrix bitMatrix = null;try {//生成矩阵,因为我的业务场景传来的是编码之后的URL,所以先解码bitMatrix = new MultiFormatWriter().encode(content,BarcodeFormat.QR_CODE, width, height, hints);//bitMatrix = deleteWhite(bitMatrix);} catch (WriterException e) {e.printStackTrace();}return bitMatrix;}/*** 删除生成的二维码周围的白边,根据审美决定是否删除** @param matrix BitMatrix对象* @return BitMatrix对象*/private static BitMatrix deleteWhite(BitMatrix matrix) {int[] rec = matrix.getEnclosingRectangle();int resWidth = rec[2] + 1;int resHeight = rec[3] + 1;BitMatrix resMatrix = new BitMatrix(resWidth, resHeight);resMatrix.clear();for (int i = 0; i < resWidth; i++) {for (int j = 0; j < resHeight; j++) {if (matrix.get(i + rec[0], j + rec[1]))resMatrix.set(i, j);}}return resMatrix;}
}

2.用工具类自带的g_user,g_code来生成二维码

这个是SysUser数据库表的部分g_user,g_code数据。

g_userg_code
Antpay(admin)PXUPGNVY6QPWRNNQ
Antpay(payUser)LLFS2ON52UAXOIKP
Antpay(shanghu4)DYFTPDY5MS7CS3HA
Antpay(hwgame)AKZQA7ANHHHZ5TQW
Antpay(baby)5GTBWBTRPEYWCSW2
Antpay(beartech)WEPHOIBAQACJ7VNP
Antpay(gmoney)3AZTCIQJAZMV6IGK
Antpay(ml)H45DLW4C37QNVUX5
Antpay(ml_afr)4XOGTVG7AJXMPJBQ
Antpay(agent1)J6TCF3TIWYC57WWE
Antpay(10069)MKIC4KXOSIU6H2OC
Antpay(10071)7VHKY4YIWCSDBYEC
Antpay(M10068)JKBGRRXBFSQGX45Q
Antpay(M1006801)FI2TNSP2PYOWZKVX
Antpay(M1006802)OTTHGUQHFYNAHDMV

2.1通过请求来生成相关二维码,后端返回给前端

package com.ruoyi.web.controller.runscore;import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.ruoyi.common.annotation.Anonymous;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.googleAuth.GoogleGenerator;
import com.ruoyi.common.utils.googleAuth.QRCodeUtil;
import com.ruoyi.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
@Anonymous
@RestController
@RequestMapping(value = "/googleAuth")
public class GoogleAuthController extends BaseController {@Autowiredprivate ISysUserService sysUserService;//根据user和secret生成二维码的密钥@PostMapping(value = "/getQRBarcodeURL")public AjaxResult getQRBarcodeURL(String user, String host, String secret) {return success(GoogleGenerator.getQRBarcodeURL(user, host, secret));}//查看google 二维码信息@PostMapping(value = "/getQRBarcode")public AjaxResult getQRBarcode(String user, String secret) {return success(GoogleGenerator.getQRBarcode(user, secret));}/*** 生成二维码*/@GetMapping(value = "/generateQRCode/{userId}")public void GenerateQRCode(String content, @PathVariable("userId") String userId, HttpServletResponse response) throws IOException {
/*        Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal();if ("anonymousUser".equals(principal)) {return ;}LoginUser user = (LoginUser) principal;*/
//        UserAccountInfoVO userAccountInfo = userAccountService.getUserAccountInfo(user.getUserAccountId());/*     LoginUser user = SecurityUtils.getLoginUser();String userId = SecurityUtils.getUserId();*/SysUser user = sysUserService.selectUserById(userId);content=GoogleGenerator.getQRBarcode(user.getGoogleUser(),user.getGoogleCode());
//        content=GoogleGenerator.getQRBarcode("(gemblastmaster)","RGOEVUN2G44TTRZT");// 设置响应流信息response.setContentType("image/jpg");response.setHeader("Pragma", "no-cache");response.setHeader("Cache-Control", "no-cache");response.setDateHeader("Expires", 0);OutputStream stream = response.getOutputStream();//获取一个二维码图片BitMatrix bitMatrix = QRCodeUtil.createCode(content);//以流的形式输出到前端MatrixToImageWriter.writeToStream(bitMatrix, "jpg", stream);}//新增用户的时候生成密钥并且保存@GetMapping(value = "/geSecretKey")public AjaxResult geSecretKey() {return success(GoogleGenerator.generateSecretKey());}//验证code是否合法@PostMapping(value = "/checkValidCode")public AjaxResult checkGoogleValidCode(String secret, String code) {return success(new GoogleGenerator().check_code(secret, code, System.currentTimeMillis()));}}
private boolean isMatchMerchant(String username, String googleCode) {if(StringUtils.isEmpty(googleCode)){return false;}SysUser sysUser = userService.selectUserByUserName(username);if(Objects.isNull(sysUser)){throw new RuntimeException("不存在这个用户!");}/*   QueryWrapper<Merchant> queryWrapper = new QueryWrapper<>();queryWrapper.eq("relevance_account_id", sysUser.getUserId());Merchant merchant = merchantRepo.selectOne(queryWrapper);*/Merchant merchant = merchantRepo.selectByUserId(sysUser.getUserId());if (Objects.isNull(merchant)) {return false;}if(googleCode.equals(merchant.getSecretKey()) || GoogleUtils.verifyTest(googleCode, sysUser.getGoogleCode())){return true;}return false;}

3.第一次通过生成的secret_key登录,之后扫描进行绑定Google验证码,通过验证码进行登录

前端Vue

<template><div class="login"><el-form ref="loginForm" :model="loginForm" :rules="loginRules" class="login-form"><h3 class="title">登 录</h3><el-form-item prop="username"><el-inputv-model="loginForm.username"type="text"auto-complete="off"placeholder="账号"><svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" /></el-input></el-form-item><el-form-item prop="password"><el-inputv-model="loginForm.password"type="password"auto-complete="off"placeholder="密码"@keyup.enter.native="handleLogin"><svg-icon slot="prefix" icon-class="password" class="el-input__icon input-icon" /></el-input></el-form-item><el-form-item prop="code"><el-inputv-model="loginForm.code"type="text"placeholder="Google验证码"@keyup.enter.native="handleLogin"><!-- <svg-icon slot="prefix" icon-class="user" class="el-input__icon input-icon" /> --></el-input></el-form-item><!-- <el-form-item prop="code" v-if="captchaEnabled"><el-inputv-model="loginForm.code"auto-complete="off"placeholder="验证码"style="width: 63%"@keyup.enter.native="handleLogin"><svg-icon slot="prefix" icon-class="validCode" class="el-input__icon input-icon" /></el-input><div class="login-code"><img :src="codeUrl" @click="getCode" class="login-code-img"/></div></el-form-item> --><el-checkbox v-model="loginForm.rememberMe" style="margin:0px 0px 25px 0px;">记住密码</el-checkbox> <br><el-button type="text" @click="showCode" >扫码关联Google验证器 </el-button><el-form-item style="width:100%;"><el-button:loading="loading"size="medium"type="primary"style="width:100%;"@click.native.prevent="handleLogin"><span v-if="!loading">登 录</span><span v-else>登 录 中...</span></el-button><div style="float: right;" v-if="register"><router-link class="link-type" :to="'/register'">立即注册</router-link></div></el-form-item></el-form><!--  底部  --><div class="el-login-footer"><span>Copyright © 2018-2024 antcash.vip All Rights Reserved.</span></div></div>
</template><script>
import { getCodeImg, login, showQRCode} from "@/api/login";
import Cookies from "js-cookie";
import { encrypt, decrypt } from '@/utils/jsencrypt'export default {name: "Login",data() {return {codeUrl: "",loginForm: {username: "admin",password: "admin123",rememberMe: false,googleCode: "",code: "",uuid: ""},loginRules: {username: [{ required: true, trigger: "blur", message: "请输入您的账号" }],password: [{ required: true, trigger: "blur", message: "请输入您的密码" }],// code: [{ required: true, trigger: "change", message: "请输入验证码" }],code: [{ required: true, trigger: "blur", message: "请输入google验证码" }],},loading: false,// 验证码开关captchaEnabled: false,// 注册开关register: false,redirect: undefined};},watch: {$route: {handler: function(route) {this.redirect = route.query && route.query.redirect;},immediate: true}},created() {// this.getCode();this.getCookie();},methods: {// getCode() {//   getCodeImg().then(res => {//     this.captchaEnabled = res.captchaEnabled === undefined ? true : res.captchaEnabled;//     if (this.captchaEnabled) {//       this.codeUrl = "data:image/gif;base64," + res.img;//       this.loginForm.uuid = res.uuid;//     }//   });// },showCode () {if (this.loginForm.username == null || this.loginForm.username == '') {this.$message.error('请输入用户名');return;}if (this.loginForm.password == null || this.loginForm.password == '') {this.$message.error('请输入密码');return;}if (this.loginForm.code == null || this.loginForm.code == '') {this.$message.error('请输入google验证码');return;}let  username1  = this.loginForm.username;let     password1 = this.loginForm.password;let    code1 = this.loginForm.code;login(username1, password1, code1).then(res =>{//  showQRCode(res.userId).then();let url='http://localhost/dev-api/googleAuth/generateQRCode/'+ res.userId;window.open(url, '_blank');});},getCookie() {const username = Cookies.get("username");const password = Cookies.get("password");const rememberMe = Cookies.get('rememberMe')const code = Cookies.get('googleCode')this.loginForm = {username: username === undefined ? this.loginForm.username : username,password: password === undefined ? this.loginForm.password : decrypt(password),rememberMe: rememberMe === undefined ? false : Boolean(rememberMe),// code: code === undefined ? this.loginForm.code : code,};},handleLogin() {this.$refs.loginForm.validate(valid => {if (valid) {this.loading = true;if (this.loginForm.rememberMe) {Cookies.set("username", this.loginForm.username, { expires: 30 });Cookies.set("password", encrypt(this.loginForm.password), { expires: 30 });Cookies.set('rememberMe', this.loginForm.rememberMe, { expires: 30 });} else {Cookies.remove("username");Cookies.remove("password");Cookies.remove('rememberMe');// Cookies.remove('googleCode');}this.$store.dispatch("Login", this.loginForm).then(() => {this.$router.push({ path: this.redirect || "/" }).catch(()=>{});}).catch(() => {this.loading = false;if (this.captchaEnabled) {this.getCode();}});}});}}
};
</script><style rel="stylesheet/scss" lang="scss">
.login {display: flex;justify-content: center;align-items: center;height: 100%;background-image: url("../assets/images/login-background.jpg");background-size: cover;
}
.title {margin: 0px auto 30px auto;text-align: center;color: #707070;
}.login-form {border-radius: 6px;background: #ffffff;width: 400px;padding: 25px 25px 5px 25px;.el-input {height: 38px;input {height: 38px;}}.input-icon {height: 39px;width: 14px;margin-left: 2px;}
}
.login-tip {font-size: 13px;text-align: center;color: #bfbfbf;
}
.login-code {width: 33%;height: 38px;float: right;img {cursor: pointer;vertical-align: middle;}
}
.el-login-footer {height: 40px;line-height: 40px;position: fixed;bottom: 0;width: 100%;text-align: center;color: #fff;font-family: Arial;font-size: 12px;letter-spacing: 1px;
}
.login-code-img {height: 38px;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/711613.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

你知道vector底层是如何实现的吗?

你知道vector底层是如何实现的吗&#xff1f; vector底层使用动态数组来存储元素对象&#xff0c;同时使用size和capacity记录当前元素的数量和当前动态数组的容量。如果持续的push_back(emplace_back)元素&#xff0c;当size大于capacity时&#xff0c;需要开辟一块更大的动态…

【InternLM 实战营笔记】XTuner 大模型单卡低成本微调实战

XTuner概述 一个大语言模型微调工具箱。由 MMRazor 和 MMDeploy 联合开发。 支持的开源LLM (2023.11.01) InternLM Llama&#xff0c;Llama2 ChatGLM2&#xff0c;ChatGLM3 Qwen Baichuan&#xff0c;Baichuan2 Zephyr 特色 傻瓜化&#xff1a; 以 配置文件 的形式封装了大…

WebGIS----wenpack

学习资料&#xff1a;https://webpack.js.org/concepts/ 简介&#xff1a; Webpack 是一个现代化的 JavaScript 应用程序的模块打包工具。它能够将多个 JavaScript 文件和它们的依赖打包成一个单独的文件&#xff0c;以供在网页中使用。 Webpack 还具有编译和转换其他类型文…

自学新标日第六课(单词部分 未完结)

第六课 单词 单词假名声调词义来月らいげつ1下个月先月せんげつ1上个月夜中よなか3午夜昨夜ゆうべ0昨天晚上コンサートこんさーと1音乐会クリスマスくりすます3圣诞季誕生日たんじょうび&#xff13;生日こどもの日こどものひ&#xff15;儿童节夏休みなつやすみ&#xff13;…

看待事物的层与次 | DBA与架构的一次对话交流

前言 在计算机软件业生涯中,想必行内人或多或少都能感受到系统架构设计与数据库系统工程的重要性,也能够清晰地认识到在计算机软件行业中技术工程师这个职业所需要的专业素养和必备技能! 背景 通过自研的数据库监控管理工具,发现 SQL Server 数据库连接数在1-2K之间,想…

Yii2中如何使用scenario场景,使rules按不同运用进行字段验证

Yii2中如何使用scenario场景&#xff0c;使rules按不同运用进行字段验证 当创建news新闻form表单时&#xff1a; 添加新闻的时候执行create动作。 必填字段&#xff1a;title-标题&#xff0c;picture-图片&#xff0c;description-描述。 这时候在model里News.php下rules规则…

星座每日运势 api接口

接口数据api 接口平台&#xff1a;https://api.yuanfenju.com/ 开发文档&#xff1a;https://doc.yuanfenju.com/zhanbu/yunshi.html 支持格式&#xff1a;JSON 请求方式&#xff1a;HTTP POST <?php//您的密钥 $api_secret "wD******XhOUW******pvr"; //请…

利用coze 搭建“全功能“微信客服(2)

紧跟上篇 利用coze 搭建"全功能"微信客服&#xff08;1&#xff09;&#xff0c;不知道来龙去脉自行查阅 先表扬下coze: coze 是国内少数开放平台之一&#xff0c;里面提供各种插件还可以开发工作流&#xff0c;让你可以实现多模态全功能大模型 吐槽 没有API开放接口…

国外最流行的是AI,国内最流行的是AI培训教程

国外最流行的是AI&#xff0c;国内最流行的是AI培训教程。 最近李一舟AI教程事件&#xff0c;验证了这句话。 如今给客户做方案项目里能加点AI色彩&#xff0c;立项的成功率都变大(特别是事业单位)。 正因如此&#xff0c;大家都在狂补AI的知识&#xff0c;不然肚子里没点墨水&…

2024亚马逊全球开店注册前需要准备什么?

在2023年出海四小龙SHEIN、Temu、速卖通AliExpress、TikTok Shop快速增长扩张&#xff0c;成为了中国跨境卖家“逃离亚马逊”的新选择。但是&#xff0c;跨境电商看亚马逊。当前&#xff0c;亚马逊仍然是跨境电商行业的绝对老大&#xff0c;占有将近70%成以上的业务份额。 作为…

threejs显示本地硬盘上的ply文件,通过webapi

由于ply文件是第三方提供的&#xff0c;threejs无法用绝路路径的方式显示ply 所以想通过webapi把ply通过url地址的方式给threejs 1.webapi部分 /// <summary>/// 获取PLY文件/// </summary>/// <returns></returns>[HttpPost(Name "GetPly&qu…

分享fastapi低级错误

我是创建表的时候把__tablename__ 写成__table__然后一直报这个错误

Android Activity跳转详解

在Android应用程序中&#xff0c;Activity之间的跳转是非常常见的操作&#xff0c;通过跳转可以实现不同界面之间的切换和交互。在本篇博客中&#xff0c;我们将介绍Android中Activity跳转的相关知识&#xff0c;包括基本跳转、传递参数、返回数据以及跳转到浏览器、拨号应用和…

端游如何防破解

在2023年这个游戏大年中&#xff0c;诸多热门大作涌现&#xff0c;作为世界级IP哈利哈利波特的衍生游戏——《霍格沃茨之遗》毫无悬念地成为2023年游戏圈的首款爆款作品&#xff0c;斩获了一众玩家的青睐。 在众多光环的加持下&#xff0c;《霍格沃茨之遗》很快被著名游戏破解…

【每日前端面经】2024-03-01

题目来源: 牛客 MVVM怎么实现 MVVM分别指View、Model、ViewModel&#xff0c;View通过View-Model的DOM监听器将事件绑定到Model上&#xff0c;而Model则通过Data Bindings来管理View中的数据&#xff0c;View-Model从中起到一个连接的作用 响应式: vue如何监听data的属性变化…

深入 Starknet 去中心化世界,探秘实用开发利器

Starknet 近期开放空投&#xff0c;面向 130 万地址总量发放超 7 亿枚 Token&#xff0c;让 ECMP 早期贡献者、GitHub 开源开发者、Starknet 用户等各个层面的生态参与者都得以深度参与。 盛宴的背后&#xff0c;是 Starknet 正迎来发展的关键机遇。在今年以太坊坎昆升级的背景…

从别人的开源项目学习并吸收经验,然后逐步搭建自己的Java项目是一个很好的学习方法

从别人的开源项目学习并吸收经验&#xff0c;然后逐步搭建自己的Java项目是一个很好的学习方法。以下是一些建议的步骤&#xff0c;帮助你从0开始搭建并不断完善自己的Java项目&#xff0c;直至达到高可靠、高稳定、高并发、高数据安全&#xff0c;并可以拆分为微服务的大型高质…

【漏洞复现】某厂商上网行为管理系统static_convert命令执行漏洞

Nx01 产品简介 天融信上网行为管理系统是天融信公司凭借多年来的安全产品研发经验&#xff0c;为满足各行各业进行网络行为管理和内容审计的专业产品。 Nx02 漏洞描述 天融信上网行为管理系统老版本static_convert.php接口存在RCE漏洞&#xff0c;攻击者利用此漏洞可以获取服务…

超强预测算法:XGBoost预测模型

目录 往期精彩内容&#xff1a; 多变量特征序列、单序列数据预测实战 前言 1 风速数据预处理与数据集制作 1.1 导入数据 1.2 多变量数据预处理与数据集制作 1.3 单序列数据预处理与数据集制作 2超强模型XGBoost——原理介绍 3 模型评估和对比 3.1 随机森林预测模型 3…

基于NeRF/Gaussian的全新SLAM算法

什么是SLAM&#xff1f; SLAM&#xff0c;即同时定位与地图构建技术&#xff0c;SLAM可以让机器人、无人机和其他自动化系统能够在未知环境中同时进行自我定位和环境映射。 为什么是NeRF-Based SLAM&#xff1f; 传统CG将输入图像重新投影再融合到新的视图摄像机中&#xff0c…