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.pswp.cn/news/711613.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/711613.shtml
英文地址,請注明出處:http://en.pswp.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…