go 集成base64Captcha 支持多种验证码
base64Captcha
是一个基于 Go 语言开发的验证码生成库,主要用于在 Web 应用中集成验证码功能,以增强系统的安全性。以下是其主要特点和简介:
base64Captcha主要功能
- 验证码类型丰富:支持生成多种类型的验证码,包括纯数字、纯字母、数字与字母组合、数学公式、汉字、音频等,满足不同场景的需求。
- 多种存储方式:
- 内存存储:简单易用,低延迟,无网络开销,但无法进行数据持久化,扩展性较差,适合单机部署。
- Redis 存储:性能高,支持分布式存储,但会增加网络开销,同时具有一定的复杂度,适合多台服务器部署的场景。
- 自定义配置灵活:
- 验证码驱动:可以通过实现
Driver
接口来自定义验证码的生成逻辑,也可以使用库自带的多种驱动,如DriverString
、DriverMath
、DriverChinese
、DriverAudio
、DriverDigit
等。 - 验证码样式:支持自定义验证码的高度、宽度、噪点数量、干扰线数量、验证码长度、字符源、背景色、字体等样式参数。
- 验证码驱动:可以通过实现
- 返回格式便捷:以 base64 编码方式返回验证码图片,方便前端展示。
使用示例
以下是一个使用 base64Captcha
生成和验证验证码的简单示例:
后端代码
// example of HTTP server that uses the captcha package.
package mainimport ("encoding/json""fmt""github.com/mojocn/base64Captcha""log""net/http""time"
)// configJsonBody json request body.
type configJsonBody struct {Id stringCaptchaType stringVerifyValue stringDriverAudio *base64Captcha.DriverAudioDriverString *base64Captcha.DriverStringDriverChinese *base64Captcha.DriverChineseDriverMath *base64Captcha.DriverMathDriverDigit *base64Captcha.DriverDigit
}// var store = base64Captcha.DefaultMemStore
var store = base64Captcha.NewMemoryStore(1000, time.Minute*2)// base64Captcha create http handler
func generateCaptchaHandler(w http.ResponseWriter, r *http.Request) {//parse request parametersdecoder := json.NewDecoder(r.Body)var param configJsonBodyerr := decoder.Decode(¶m)if err != nil {log.Println(err)}defer r.Body.Close()var driver base64Captcha.Driver//choose driverswitch param.CaptchaType {case "audio":driver = param.DriverAudiocase "string":driver = param.DriverString.ConvertFonts()case "math":driver = param.DriverMath.ConvertFonts()case "chinese":driver = param.DriverChinese.ConvertFonts()default:driver = param.DriverDigit}c := base64Captcha.NewCaptcha(driver, store)id, b64s, _, err := c.Generate()body := map[string]interface{}{"code": 1, "data": b64s, "captchaId": id, "msg": "success"}if err != nil {body = map[string]interface{}{"code": 0, "msg": err.Error()}}w.Header().Set("Content-Type", "application/json; charset=utf-8")json.NewEncoder(w).Encode(body)
}// base64Captcha verify http handler
func captchaVerifyHandle(w http.ResponseWriter, r *http.Request) {//parse request parametersdecoder := json.NewDecoder(r.Body)var param configJsonBodyerr := decoder.Decode(¶m)if err != nil {log.Println(err)}defer r.Body.Close()//verify the captchabody := map[string]interface{}{"code": 0, "msg": "failed"}if store.Verify(param.Id, param.VerifyValue, true) {body = map[string]interface{}{"code": 1, "msg": "ok"}}//set json responsew.Header().Set("Content-Type", "application/json; charset=utf-8")json.NewEncoder(w).Encode(body)
}// start a net/http server
func main() {//serve Vuejs+ElementUI+Axios Web Applicationhttp.Handle("/", http.FileServer(http.Dir("./static")))//api for create captchahttp.HandleFunc("/api/getCaptcha", generateCaptchaHandler)//api for verify captchahttp.HandleFunc("/api/verifyCaptcha", captchaVerifyHandle)fmt.Println("Server is at :9599")if err := http.ListenAndServe(":9599", nil); err != nil {log.Fatal(err)}
}
前端页面
<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>Config Parameter Playground</title><meta name="Keywords" content="golang,godoc,captcha,base64,png,图像验证码"/><meta name="Description" content="Base64 Captcha"/><link rel="stylesheet" href="https://cdn.bootcss.com/element-ui/2.0.11/theme-chalk/index.css"><style>.el-header, .el-footer {background-color: #B3C0D1;color: #333;text-align: center;line-height: 0px;}.el-header > p {margin-top: 12px !important;}.el-main {background-color: #E9EEF3;color: #333;text-align: center;/*line-height: 160px;*/}body {margin: 0px;text-align: center;}.login-container {-webkit-border-radius: 5px;border-radius: 5px;-moz-border-radius: 5px;background-clip: padding-box;margin: 15px auto auto auto;width: 480px;padding: 6px;background: #fff;border: 1px solid #eaeaea;box-shadow: 0 0 25px #cac6c6;}.title {margin: 0px auto 20px auto;text-align: center;color: #505458;}.captcha-img {cursor: pointer;position: relative;border: 1px solid chartreuse;box-shadow: 0 0 6px #cac6c6;}.el-form-item {margin-bottom: 0px;}.el-main {background-color: #E9EEF3;color: #333;text-align: center;padding: 0px !important;}</style><!-- Place this tag in your head or just before your close body tag. --><script src="https://buttons.github.io/buttons.js"></script><script src="https://cdn.bootcss.com/vue/2.5.13/vue.min.js"></script><script src="https://cdn.bootcss.com/element-ui/2.0.11/index.js"></script><script src="https://cdn.bootcss.com/axios/0.17.1/axios.min.js"></script>
</head>
<body>
<div id="app"><el-container><el-headerstyle="height: 90px!important;"><!-- Place this tag where you want the button to render. --><p><a class="github-button" href="https://github.com/mojocn/base64captcha" data-size="large"data-show-count="true" aria-label="Star mojocn/base64captcha on GitHub">Star</a><!-- Place this tag where you want the button to render. --><a class="github-button" href="https://github.com/mojocn" data-size="large" data-show-count="true"aria-label="Follow @mojocn on GitHub">Follow @mojocn</a><a class="github-button" href="https://github.com/JJJJJJJerk" data-size="large" data-show-count="true"aria-label="Follow @mojocn on GitHub">Follow @Eric Zhou</a><!-- Place this tag where you want the button to render. --><a class="github-button" href="https://github.com/mojocn/base64captcha/issues" data-size="large"data-show-count="true" aria-label="Issue mojocn/base64captcha on GitHub">Issue</a><!-- Place this tag where you want the button to render. --><a class="github-button" href="https://github.com/mojocn/base64captcha/archive/master.zip"data-size="large" aria-label="Download mojocn/base64captcha on GitHub">Download</a></p><a href="https://godoc.org/github.com/mojocn/base64Captcha" rel="nofollow"><imgsrc="https://camo.githubusercontent.com/600bdcf87a3b63b5300c6673401901196360a82a/68747470733a2f2f676f646f632e6f72672f6769746875622e636f6d2f6d6f6a6f636e2f626173653634436170746368613f7374617475732e737667"alt="GoDoc" data-canonical-src="https://godoc.org/github.com/mojocn/base64Captcha?status.svg"style="max-width:100%;"></a><a href="https://goreportcard.com/report/github.com/mojocn/base64Captcha" rel="nofollow"><imgsrc="https://camo.githubusercontent.com/0848346ead4693b8b2d975d8cbbb032945fb708d/68747470733a2f2f676f7265706f7274636172642e636f6d2f62616467652f6769746875622e636f6d2f6d6f6a6f636e2f62617365363443617074636861"alt="Go Report Card"data-canonical-src="https://goreportcard.com/badge/github.com/mojocn/base64Captcha"style="max-width:100%;"></a><a href="http://golangfoundation.org" rel="nofollow"><imgsrc="https://camo.githubusercontent.com/36f4996a1c92724272c100659936593ff0909a29/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f476f6c616e672d466f756e646174696f6e2d677265656e2e737667"alt="Foundation" data-canonical-src="https://img.shields.io/badge/Golang-Foundation-green.svg"style="max-width:100%;"></a><a href="https://codecov.io/gh/mojocn/base64Captcha"><img src="https://codecov.io/gh/mojocn/base64Captcha/branch/master/graph/badge.svg"/></a><a href="http://doge.mit-license.org"><imgsrc="https://camo.githubusercontent.com/3d7aa1ddbfa86368152bf42123c17b69ea8070be/687474703a2f2f696d672e736869656c64732e696f2f3a6c6963656e73652d6d69742d626c75652e737667"alt="License" data-canonical-src="http://img.shields.io/:license-mit-blue.svg"style="max-width:100%;"></a><a href="https://camo.githubusercontent.com/69f50fbca17d6577018651ff9afcb55cdac03bc4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f73746162696c6974792d737461626c652d627269676874677265656e2e737667"target="_blank"><imgsrc="https://camo.githubusercontent.com/69f50fbca17d6577018651ff9afcb55cdac03bc4/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f73746162696c6974792d737461626c652d627269676874677265656e2e737667"alt="stability-stable"data-canonical-src="https://img.shields.io/badge/stability-stable-brightgreen.svg"style="max-width:100%;"></a></p></el-header><el-main><el-row style="width: 50%;margin:8px auto;background: #9e9e9e;padding: 8px 2rem" type="flex"justify="center" align="middle"><el-col :span="16"><img @click.prevent="generateCaptcha" :src="blob" class="captcha-img"v-if="form.CaptchaType !== 'audio'"/><audio controls :src="blob" autoplay v-if="form.CaptchaType === 'audio'"/></el-col><el-col :span="8"><el-form><el-form-item><el-inputtype="text"v-model="form.VerifyValue"auto-complete="off"style="margin: 0 auto 8px auto"placeholder="input your captcha numbers"></el-input></el-form-item><el-form-item><el-buttontype="primary"style="width:100%"v-loading="loading"@click.native.prevent="submitForm">Verify Captcha</el-button></el-form-item></el-form></el-col></el-row><el-tabs v-model="form.CaptchaType"style="width: 70%;margin-left: auto;margin-right: auto;"type="border-card" @tab-click="handleClick"><el-tab-pane label="DriverDigit" name="digit"><el-formlabel-width="280px"label-position="left"><el-form-item label="DriverDigit.Length"><el-slider v-model="form.DriverDigit.Length" :min="1" :max="10" show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverDigit.Width"><el-slider v-model="form.DriverDigit.Width" :min="20" :max="480" :step="5"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverDigit.Height"><el-slider v-model="form.DriverDigit.Height" :min="20" :max="180" :step="5"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverDigit.MaxSkew"><el-slider v-model="form.DriverDigit.MaxSkew" :step="0.05" :min="0.1" :max="1"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverDigit.DotCount"><el-slider v-model="form.DriverDigit.DotCount" :min="2" :max="100" show-input@change="generateCaptcha"></el-slider></el-form-item></el-form></el-tab-pane><el-tab-pane label="DriverString" name="string"><el-formlabel-width="280px"label-position="left"><el-form-item label="DriverString.Length"><el-slider v-model="form.DriverString.Length" :min="1" :max="10" show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverString.Source"><el-input v-model.trim="form.DriverString.Source"type="textarea"placeholder="Any Unicode string is OK, Korean Japanese Greek Arabic Thai ..."@change="generateCaptcha"></el-input></el-form-item><el-form-item label="DriverString.Width"><el-slider v-model="form.DriverString.Width" :min="20" :max="480" :step="5"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverString.Height"><el-slider v-model="form.DriverString.Height" :min="20" :max="180" :step="5"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverString.NoiseCount"><el-slider v-model="form.DriverString.NoiseCount" :min="0" :max="480" :step="5"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverString.ShowLineOptions"><el-checkbox-group v-model="form.ShowLineOptions" @change="generateCaptcha"><el-checkbox label="2">OptionShowHollowLine</el-checkbox><el-checkbox label="4">OptionShowSlimeLine</el-checkbox><el-checkbox label="8">OptionShowSineLine</el-checkbox></el-checkbox-group></el-form-item><el-form-item label="DriverString.Fonts"><el-checkbox-group v-model="form.DriverString.Fonts" @change="generateCaptcha"><el-checkbox v-for="f in fonts" :label="f" :key="f">{{f}}</el-checkbox></el-checkbox-group></el-form-item><el-form-item label="DriverString.BgColor."><el-form-item label="R"><el-slider v-model="form.DriverString.BgColor.R" :min="0" :max="254" :step="1"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="G"><el-slider v-model="form.DriverString.BgColor.G" :min="0" :max="254" :step="1"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="B"><el-slider v-model="form.DriverString.BgColor.B" :min="0" :max="254" :step="1"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="A"><el-slider v-model="form.DriverString.BgColor.A" :min="0" :max="254" :step="1"show-input@change="generateCaptcha"></el-slider></el-form-item></el-form-item></el-form></el-tab-pane><el-tab-pane label="DriverMath" name="math"><el-formlabel-width="280px"label-position="left"><el-form-item label="DriverMath.Width"><el-slider v-model="form.DriverMath.Width" :min="20" :max="480" :step="5"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverMath.Height"><el-slider v-model="form.DriverMath.Height" :min="20" :max="180" :step="5"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverMath.NoiseCount"><el-slider v-model="form.DriverMath.NoiseCount" :min="0" :max="480" :step="5"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverMath.ShowLineOptions"><el-checkbox-group v-model="form.ShowLineOptions" @change="generateCaptcha"><el-checkbox label="2">OptionShowHollowLine</el-checkbox><el-checkbox label="4">OptionShowSlimeLine</el-checkbox><el-checkbox label="8">OptionShowSineLine</el-checkbox></el-checkbox-group></el-form-item><el-form-item label="DriverMath.Fonts"><el-checkbox-group v-model="form.DriverMath.Fonts" @change="generateCaptcha"><el-checkbox v-for="f in fonts" :label="f" :key="f">{{f}}</el-checkbox></el-checkbox-group></el-form-item><el-form-item label="DriverMath.BgColor."><el-form-item label="R"><el-slider v-model="form.DriverMath.BgColor.R" :min="0" :max="254" :step="1"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="G"><el-slider v-model="form.DriverMath.BgColor.G" :min="0" :max="254" :step="1"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="B"><el-slider v-model="form.DriverMath.BgColor.B" :min="0" :max="254" :step="1"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="A"><el-slider v-model="form.DriverMath.BgColor.A" :min="0" :max="254" :step="1"show-input@change="generateCaptcha"></el-slider></el-form-item></el-form-item></el-form></el-tab-pane><el-tab-pane label="DriverChinese" name="chinese"><el-formlabel-width="280px"label-position="left"><el-form-item label="DriverChinese.Length"><el-slider v-model="form.DriverChinese.Length" :min="1" :max="10" show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverChinese.Source"><el-input v-model.trim="form.DriverChinese.Source"type="textarea"placeholder="可以是英文逗号分隔的词组"@change="generateCaptcha"></el-input></el-form-item><el-form-item label="DriverChinese.Width"><el-slider v-model="form.DriverChinese.Width" :min="20" :max="480" :step="5"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverChinese.Height"><el-slider v-model="form.DriverChinese.Height" :min="20" :max="180" :step="5"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverChinese.NoiseCount"><el-slider v-model="form.DriverChinese.NoiseCount" :min="0" :max="480" :step="5"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverChinese.ShowLineOptions"><el-checkbox-group v-model="form.ShowLineOptions" @change="generateCaptcha"><el-checkbox label="2">OptionShowHollowLine</el-checkbox><el-checkbox label="4">OptionShowSlimeLine</el-checkbox><el-checkbox label="8">OptionShowSineLine</el-checkbox></el-checkbox-group></el-form-item><el-form-item label="DriverChinese.Fonts"><el-checkbox-group v-model="form.DriverChinese.Fonts" @change="generateCaptcha"><el-checkbox v-for="f in fonts" :label="f" :key="f">{{f}}</el-checkbox></el-checkbox-group></el-form-item><el-form-item label="DriverChinese.BgColor."><el-form-item label="R"><el-slider v-model="form.DriverChinese.BgColor.R" :min="0" :max="254" :step="1"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="G"><el-slider v-model="form.DriverChinese.BgColor.G" :min="0" :max="254" :step="1"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="B"><el-slider v-model="form.DriverChinese.BgColor.B" :min="0" :max="254" :step="1"show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="A"><el-slider v-model="form.DriverChinese.BgColor.A" :min="0" :max="254" :step="1"show-input@change="generateCaptcha"></el-slider></el-form-item></el-form-item></el-form></el-tab-pane><el-tab-pane label="DriverAudio" name="audio"><el-formlabel-width="280px"label-position="left"><el-form-item label="DriverAudio.Length"><el-slider v-model="form.DriverAudio.Length" :min="1" :max="10" show-input@change="generateCaptcha"></el-slider></el-form-item><el-form-item label="DriverAudio.Language"><el-radio-group v-model="form.DriverAudio.Language" @change="generateCaptcha"><el-radio-button label="en"></el-radio-button><el-radio-button label="zh"></el-radio-button><el-radio-button label="ru"></el-radio-button><el-radio-button label="ja"></el-radio-button></el-radio-group></el-form-item></el-form></el-tab-pane></el-tabs></el-main><el-footerstyle="line-height: 60px;margin-top: 1rem"> https://github.com/dejavuzhou/felix<a href="https://github.com/mojocn" type="success">https://github.com/mojocn</a><a href="https://mojotv.cn" type="success">Golang Tech Blog </a></el-footer></el-container></div>
</body><script>new Vue({el: '#app',data: function () {return {fonts: ["3Dumb.ttf","ApothecaryFont.ttf","Comismsh.ttf","DENNEthree-dee.ttf","DeborahFancyDress.ttf","Flim-Flam.ttf","RitaSmith.ttf","actionj.ttf","chromohv.ttf","wqy-microhei.ttc",],form: {ShowLineOptions: [],CaptchaType: "string",Id: '',VerifyValue: '',DriverAudio: {Length: 6,Language: 'zh'},DriverString: {Height: 60,Width: 240,ShowLineOptions: 0,NoiseCount: 0,Source: "1234567890qwertyuioplkjhgfdsazxcvbnm",Length: 6,Fonts: ["wqy-microhei.ttc"],BgColor: {R: 0, G: 0, B: 0, A: 0},},DriverMath: {Height: 60,Width: 240,ShowLineOptions: 0,NoiseCount: 0,Length: 6,Fonts: ["wqy-microhei.ttc"],BgColor: {R: 0, G: 0, B: 0, A: 0},},DriverChinese: {Height: 60,Width: 320,ShowLineOptions: 0,NoiseCount: 0,Source: "设想,你在,处理,消费者,的音,频输,出音,频可,能无,论什,么都,没有,任何,输出,或者,它可,能是,单声道,立体声,或是,环绕立,体声的,,不想要,的值",Length: 2,Fonts: ["wqy-microhei.ttc"],BgColor: {R: 125, G: 125, B: 0, A: 118},},DriverDigit: {Height: 80,Width: 240,Length: 5,MaxSkew: 0.7,DotCount: 80}},blob: "",loading: false}},computed: {DriverStringSequencedCharacters: {get: function () {return this.form.DriverString.SequencedCharacters.join(',')},set: function (newValue) {this.form.DriverString.SequencedCharacters = newValue.split(',')}}},methods: {doShowLineOptions(val) {if (val > 0) {this.ShowLineOptions = this.form.ShowLineOptions | val;} else {}},formatTooltip: function (val) {var items = ['CaptchaModeNumber', 'CaptchaModeAlphabet', 'CaptchaModeArithmetic','CaptchaModeNumberAlphabet', 'CaptchaModeChinese', 'CaptchaModeUseSequencedCharacters'];return items[val];},handleClick: function (tab, event) {this.generateCaptcha();},generateCaptcha: function () {this.loading = true;//generate uuid string so the serve can verify numbers in the png//you can generate the captchaId in other wayvar that = this;var opt = 0;this.form.ShowLineOptions.forEach(item => {opt = opt | item;});this.form.DriverString.ShowLineOptions = opt;this.form.DriverMath.ShowLineOptions = opt;//this.form.DriverChineseWords.ShowLineOptions = opt;// the api/getCaptcha endpoint only recieve captchaId paramenteraxios.post('/api/getCaptcha', that.form).then(function (response) {that.loading = false;that.form.Id = response.data.captchaId;that.blob = response.data.data;}).catch(function (error) {that.loading = false;that.$notify({title: 500,message: 'net work or server error',type: "error"});});},submitForm: function () {var that = this;this.loading = true;axios.post('/api/verifyCaptcha', that.form).then(function (response) {that.loading = false;that.$notify({title: response.data.msg,message: response.data.data,type: response.data.code});if (response.data.code === "success") {that.generateCaptcha(false)}}).catch(function (error) {that.loading = false;that.$notify({title: 500,message: 'net work or server error',type: "error"});});}},mounted: function () {this.generateCaptcha()}})</script>
</html>
效果
适用场景
- 用户登录:防止暴力破解密码。
- 注册验证:确保注册用户为真人操作。
- 敏感操作:如修改密码、支付等操作前的二次验证。
相关文章:

go 集成base64Captcha 支持多种验证码
base64Captcha 是一个基于 Go 语言开发的验证码生成库,主要用于在 Web 应用中集成验证码功能,以增强系统的安全性。以下是其主要特点和简介: base64Captcha主要功能 验证码类型丰富:支持生成多种类型的验证码,包括纯…...

【C语言字符函数和字符串函数(一)】--字符分类函数,字符转换函数,strlen,strcpy,strcat函数的使用和模拟实现
目录 一.字符分类函数 1.1--字符分类函数的理解 1.2--字符分类函数的使用 二.字符转换函数 2.1--字符转换函数的理解 2.2--字符转换函数的使用 三.strlen的使用和模拟实现 3.1--strlen的使用演示 3.2--strlen的返回值 3.3--strlen的模拟实现 四.strcpy的使用和模拟实现…...
deepseek问答记录:请讲解一下hugingface transformers中的AutoProcessor
Hugging Face Transformers库中的AutoProcessor是一个用于自动加载与预训练模型配套的处理器的工具类。它简化了预处理流程,特别适用于多模态模型(如同时处理文本、图像、音频的模型)。以下是详细讲解: 1. AutoProcessor的功能 •…...

大模型基础之量化
概述 量化,Quantization,机器学习和深度学习领域是一种用于降低计算复杂度、减少内存占用、加速推理的优化方法。定义:将模型中的数据从高精度表示转换为低精度表示。主要目的是为了减少模型的存储需求和计算复杂度,同时尽量减少…...

游戏引擎学习第286天:开始解耦实体行为
回顾并为今天的内容定下基调 我们目前正在进入实体系统的一个新阶段,之前我们已经让实体的移动系统变得更加灵活,现在我们想把这个思路继续延伸到实体系统的更深层次。今天的重点,是重新审视我们处理实体类型(entity type&#x…...

win10-django项目与mysql的基本增删改查
以下都是在win10系统下,django项目的orm框架对本地mysql的表的操作 models.py----->即表对应的类所在的位置 在表里新增数据 1.引入表对应的在models.py中的类class 2.在views.py中使用函数:类名.objects.create(字段名值,字段名"值"。。。…...
Windows 本地部署MinerU详细教程
📖 项目概述 MinerU是一款由OpenDataLab开发的开源PDF转Markdown工具,可以高质量地提取PDF文档内容,生成结构化的Markdown格式文本。本指南将帮助您在本地部署并使用MinerU。 ⭐ 功能特性 MinerU具有以下核心功能: ✨ 文档处理…...

动态范围调整(SEF算法实现)
一、背景介绍 继续在整理对比度调整相关算法,发现一篇单帧动态范围提升的算法:Simulated Exposure Fusion,论文表现看起来很秀,这里尝试对它进行了下效果复现。 二、实现流程 1、基本原理 整体来说,大致可以分为两步…...

SpringCloud微服务开发与实战
本节内容带你认识什么是微服务的特点,微服务的拆分,会使用Nacos实现服务治理,会使用OpenFeign实现远程调用(通过黑马商城来带你了解实际开发中微服务项目) 前言:从谷歌搜索指数来看,国内从自201…...

WAS和Tomcat的对比
一、WAS和Tomcat的对比 WebSphere Application Server (WAS) 和 Apache Tomcat 是两款常用的 Java 应用服务器,但它们有许多显著的区别。在企业级应用中,它们扮演不同的角色,各自有其特点和适用场景。以下是它们在多个维度上的详细对比&…...
Rust 数据结构:String
Rust 数据结构:String Rust 数据结构:String什么是字符串?创建新字符串更新字符串将 push_str 和 push 附加到 String 对象后使用 运算符和 format! 宏 索引到字符串字符串在内存中的表示字节、标量值和字形簇 分割字符串遍历字符串的方法 R…...

IntelliJ IDEA打开项目后,目录和文件都不显示,只显示pom.xml,怎样可以再显示出来?
检查.idea文件夹 如果项目目录中缺少.idea文件夹,可能导致项目结构无法正确加载。可以尝试删除项目根目录下的.idea文件夹,然后重新打开项目,IDEA会自动生成新的.idea文件夹和相关配置文件,从而恢复项目结构。 问题解决࿰…...

Hot100-链表-JS
160.相交链表 160. 相交链表 已解答 简单 相关标签 相关企业 给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。 图示两个链表在节点 c1 开始相交: 题目数据 保证 整…...

事件驱动架构:从传统服务到实时响应的IT新风潮
文章目录 事件驱动架构的本质:从请求到事件的范式转变在EDA中: 事件驱动架构的演进:从消息队列到云原生标配核心技术:事件驱动架构的基石与工具链1. 消息队列:事件传递的枢纽2. 消费者:异步处理3. 事件总线…...

网络流量分析 | NetworkMiner
介绍 NetworkMiner 是一款适用于Windows(也适用于Linux/Mac)的开源网络取证分析工具。它可被用作被动网络嗅探器/数据包捕获工具,也可被用于检测操作系统、会话、主机名、开放端口等,还能被用于解析pcap文件进行离线分析。点击此…...
弦理论的额外维度指的是什么,宇宙中有何依据
弦理论中的额外维度是解释微观世界与宏观宇宙矛盾的关键假设之一。它们并非科幻中的平行宇宙,而是通过严谨的数学框架提出,并可能留下可观测的宇宙学痕迹。以下是具体解析: 一、弦理论为何需要额外维度? 数学自洽性要求 弦理论中…...
std::tuple 用法
std::tuple 是 C11 引入的模板类,用来存储多个不同类型的值,类似于 Python 的元组。你可以把它看作是一种“组合多个变量在一个对象中”的方式。 ✅ 基本用法 #include <tuple> #include <iostream>int main() {std::tuple<int, std::st…...

深入理解 Git 分支操作的底层原理
在软件开发的世界里,Git 已经成为了版本控制的标配工具。而 Git 分支功能,更是极大地提升了团队协作和项目开发的效率。我们在日常开发中频繁地创建、切换和合并分支,但是这些操作背后的底层原理是怎样的呢?在之前的博客探秘Git底…...

Excel MCP: 自动读取、提炼、分析Excel数据并生成可视化图表和分析报告
最近,一款Excel MCP Server的开源工具火了,看起来功能很强大,咱们今天来一探究竟。 基础环境 最近两年,大家都可以看到AI的发展有多快,我国超10亿参数的大模型,在短短一年之内,已经超过了100个&…...

C语言:深入理解指针(4)
目录 一、字符指针变量 二、数组指针变量 三、二维数组传参的本质 四、函数指针变量 五、typedef 类型重命名 六、函数指针数组 一、字符指针变量 我们常见的字符指针变量是这样的: char a w; char* p &a; char arr[] "abcd"; char* pa ar…...
Gensim 是一个专为 Python 设计的开源库
Gensim 是一个专为 Python 设计的开源库,其核心代码和生态系统均基于 Python 构建,目前官方仅支持 Python 语言。如果你需要在其他编程语言中实现类似功能(如词向量训练、主题模型等),通常需要使用对应语言的替代库或通…...
质量管理工程师面试总结
今天闲着无聊参加了学校招聘会的一家双选会企业,以下是面试的过程。 此次面试采用的是一对多的形式。(此次三个求职者,一个面试官) 面试官:开始你们每个人先做个自我介绍吧。 哈哈哈哈哈哈哈哈,其实我们…...
python 爬虫框架介绍
文章目录 前言一、Requests BeautifulSoup(基础组合)二、Scrapy(高级框架)三、PySpider(可视化爬虫)四、Selenium(浏览器自动化)五、Playwright(新一代浏览器自动化&…...
window 显示驱动开发-使用有保证的协定 DMA 缓冲区模型
Windows Vista 的显示驱动程序模型保证呈现设备的 DMA 缓冲区和修补程序位置列表的大小。 修补程序位置列表包含 DMA 缓冲区中命令引用的资源的物理内存地址。 在有保证的协定模式下,用户模式显示驱动程序知道 DMA 缓冲区和修补程序位置列表的确切大小,…...
蓝牙协议架构与调试工具详解(含 BLE、HCI 命令、调试命令)
本文介绍蓝牙协议从物理层到应用层的完整通信流程,并详解了 Linux 下主流蓝牙调试工具的使用方法,适用于嵌入式蓝牙驱动开发、BLE调试、通信协议分析等场景。 🔧 1. 蓝牙架构概览 ✅ 芯片架构 单模芯片:仅支持 BLE 或 Classic 蓝…...
预测模型开发与评估:基于机器学习的数据分析实践
在当今数据驱动的时代,预测模型已成为各行各业决策制定的核心工具。本文将分享我在COMP5310课程项目中开发预测模型的经验,探讨从数据清洗到模型优化的完整过程,并提供详细的技术实现代码。 ## 研究问题与数据集 ### 研究问题 我们的研究聚焦…...
提高表达能力
你遇到的这种情况其实很常见,背后的原因可能涉及思维模式、心理状态和表达习惯的综合作用。以下是具体分析和解决方案: 1. 原因分析:为什么讨论时流畅,独自表达却卡壳? 外部反馈缺失:讨论时对方的提问、反…...

【更新】全国省市县-公开手机基站数据集(2006-2025.3)
手机基站是现代通信网络中的重要组成部分,它们为广泛的通信服务提供基础设施。随着数字化进程的不断推进,手机基站的建设与布局对优化网络质量和提升通信服务水平起着至关重要的作用,本分享数据可帮助分析移动通信网络的发展和优化。本次数据…...

基于MNIST数据集的手写数字识别(CNN)
目录 一,模型训练 1.1 数据集介绍 1.2 CNN模型层结构 1.3 定义CNN模型 1.4 神经网络的前向传播过程 1.5 数据预处理 1.6 加载数据 1.7 初始化 1.8 模型训练过程 1.9 保存模型 二,模型测试 2.1 定义与训练时相同的CNN模型架构 2.2 图像的预处…...
MYSQL创建索引的原则
创建索引的原则包括: 表中的数据量超过10万以上时考虑创建索引。 选择查询频繁的字段作为索引,如查询条件、排序字段或分组字段。 尽量使用复合索引,覆盖SQL的返回值。 如果字段区分度不高,可以将其放在组合索引的后面。 对于…...