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

基于Vue的验证码实现

一、验证码核心实现

        创建slide-verify.vue,代码如下:

<template><divclass="slide-verify":style="{ width: w + 'px' }"id="slideVerify"onselectstart="return false;"><!-- 图片加载遮蔽罩 --><div :class="{ 'slider-verify-loading': loadBlock }"></div><canvas :width="w" :height="h" ref="canvas"></canvas><div v-if="show" @click="refresh" class="slide-verify-refresh-icon"></div><canvas:width="w":height="h"ref="block"class="slide-verify-block"></canvas><!-- container --><divclass="slide-verify-slider":class="{'container-active': containerActive,'container-success': containerSuccess,'container-fail': containerFail}"><div class="slide-verify-slider-mask" :style="{ width: sliderMaskWidth }"><!-- slider --><div@mousedown="sliderDown"@touchstart="touchStartEvent"@touchmove="handleMoveEvent($event, 'touch')"@touchend="handleMoveEndEvent($event, 'touch')"class="slide-verify-slider-mask-item":style="{ left: sliderLeft }"><div class="slide-verify-slider-mask-item-icon"></div></div></div><span class="slide-verify-slider-text">{{ sliderText }}</span></div></div>
</template>
<script>
const PI = Math.PI;function sum(x, y) {return x + y;
}function square(x) {return x * x;
}
export default {name: "SlideVerify",props: {// block lengthl: {type: Number,default: 42},// block radiusr: {type: Number,default: 10},// canvas widthw: {type: Number,default: 310},// canvas heighth: {type: Number,default: 155},sliderText: {type: String,default: "Slide filled right"},accuracy: {type: Number,default: 5 // 若为 -1 则不进行机器判断},show: {type: Boolean,default: true},imgs: {type: Array,default: () => []}},data() {return {containerActive: false, // container active classcontainerSuccess: false, // container success classcontainerFail: false, // container fail classcanvasCtx: null,blockCtx: null,block: null,block_x: undefined, // container random positionblock_y: undefined,L: this.l + this.r * 2 + 3, // block real lengthimg: undefined,originX: undefined,originY: undefined,isMouseDown: false,trail: [],sliderLeft: 0, // block right offsetsliderMaskWidth: 0, // mask width,success: false, // Bug Fixes 修复了验证成功后还能滑动loadBlock: true, // Features 图片加载提示,防止图片没加载完就开始验证timestamp: null};},mounted() {this.init();},methods: {init() {this.initDom();this.initImg();this.bindEvents();},initDom() {this.block = this.$refs.block;this.canvasCtx = this.$refs.canvas.getContext("2d");this.blockCtx = this.block.getContext("2d");},initImg() {const img = this.createImg(() => {// 图片加载完关闭遮蔽罩this.loadBlock = false;this.drawBlock();this.canvasCtx.drawImage(img, 0, 0, this.w, this.h);this.blockCtx.drawImage(img, 0, 0, this.w, this.h);let { block_x: x, block_y: y, r, L } = this;let _y = y - r * 2 - 1;let ImageData = this.blockCtx.getImageData(x, _y, L, L);this.block.width = L;this.blockCtx.putImageData(ImageData, 0, _y);});this.img = img;},drawBlock() {this.block_x = this.getRandomNumberByRange(this.L + 10,this.w - (this.L + 10));this.block_y = this.getRandomNumberByRange(10 + this.r * 2,this.h - (this.L + 10));this.draw(this.canvasCtx, this.block_x, this.block_y, "fill");this.draw(this.blockCtx, this.block_x, this.block_y, "clip");},draw(ctx, x, y, operation) {let { l, r } = this;ctx.beginPath();ctx.moveTo(x, y);ctx.arc(x + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI);ctx.lineTo(x + l, y);ctx.arc(x + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI);ctx.lineTo(x + l, y + l);ctx.lineTo(x, y + l);ctx.arc(x + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true);ctx.lineTo(x, y);ctx.lineWidth = 2;ctx.fillStyle = "rgba(255, 255, 255, 0.7)";ctx.strokeStyle = "rgba(255, 255, 255, 0.7)";ctx.stroke();ctx[operation]();// Bug Fixes 修复了火狐和ie显示问题ctx.globalCompositeOperation = "destination-over";},createImg(onload) {const img = document.createElement("img");img.crossOrigin = "Anonymous";img.onload = onload;img.onerror = () => {img.src = this.getRandomImg();};img.src = this.getRandomImg();return img;},// 随机生成img srcgetRandomImg() {// return require('../assets/img.jpg')const len = this.imgs.length;return len > 0? this.imgs[this.getRandomNumberByRange(0, len - 1)]: // "https://bing.ioliu.cn/v1/rand?w=300&h=150";"https://source.unsplash.com/300x150/?book,library";// "https://api.dujin.org/pic/fengjing";},getRandomNumberByRange(start, end) {return Math.round(Math.random() * (end - start) + start);},refresh() {this.reset();this.$emit("refresh");},sliderDown(event) {if (this.success) return;this.originX = event.clientX;this.originY = event.clientY;this.isMouseDown = true;this.timestamp = +new Date();},touchStartEvent(e) {if (this.success) return;e.preventDefault();this.originX = e.changedTouches[0].pageX;this.originY = e.changedTouches[0].pageY;this.isMouseDown = true;this.timestamp = +new Date();},bindEvents() {document.addEventListener("mousemove", this.handleMoveEvent);document.addEventListener("mouseup", this.handleMoveEndEvent);},// 处理函数抽离handleMoveEvent: throttle(function(e, type = "mouse") {if (!this.isMouseDown) return false;const moveX =type === "mouse"? e.clientX - this.originX: e.changedTouches[0].pageX - this.originX;const moveY =type === "mouse"? e.clientY - this.originY: e.changedTouches[0].pageY - this.originY;if (moveX < 0 || moveX + 38 >= this.w) return false;this.sliderLeft = moveX + "px";let blockLeft = ((this.w - 40 - 20) / (this.w - 40)) * moveX;this.block.style.left = blockLeft + "px";this.containerActive = true; // add activethis.sliderMaskWidth = moveX + "px";this.trail.push(moveY);}),handleMoveEndEvent(e, type = "mouse") {if (!this.isMouseDown) return false;this.isMouseDown = false;if ((type === "mouse" && e.clientX === this.originX) ||(type === "touch" && e.changedTouches[0].pageX === this.originX))return false;this.containerActive = false; // remove activethis.timestamp = +new Date() - this.timestamp;const { spliced, TuringTest } = this.verify();if (spliced) {if (this.accuracy === -1) {this.containerSuccess = true;this.success = true;this.$emit("success", this.timestamp);return;}if (TuringTest) {// succthis.containerSuccess = true;this.success = true;this.$emit("success", this.timestamp);} else {this.containerFail = true;this.$emit("again");}} else {this.containerFail = true;this.$emit("fail");setTimeout(() => {this.reset();}, 1000);}},verify() {const arr = this.trail; // drag y move distanceconst average = arr.reduce(sum) / arr.length; // averageconst deviations = arr.map(x => x - average); // deviation arrayconst stddev = Math.sqrt(deviations.map(square).reduce(sum) / arr.length); // standard deviationconst left = parseInt(this.block.style.left);const accuracy =this.accuracy <= 1 ? 1 : this.accuracy > 10 ? 10 : this.accuracy;return {spliced: Math.abs(left - this.block_x) <= accuracy,TuringTest: average !== stddev // equal => not person operate};},reset() {this.success = false;this.containerActive = false;this.containerSuccess = false;this.containerFail = false;this.sliderLeft = 0;this.block.style.left = 0;this.sliderMaskWidth = 0;// canvaslet { w, h } = this;this.canvasCtx.clearRect(0, 0, w, h);this.blockCtx.clearRect(0, 0, w, h);this.block.width = w;// generate imgthis.img.src = this.getRandomImg();this.$emit("fulfilled");}},destroyed() {document.removeEventListener("mousemove", this.handleMoveEvent);document.removeEventListener("mouseup", this.handleMoveEndEvent);}
};function throttle(fn,interval = 50,options = { leading: true, trailing: true }
) {const { leading, trailing, resultCallback } = options;let lastTime = 0;let timer = null;const _throttle = function(...args) {return new Promise((resolve, reject) => {const nowTime = new Date().getTime();if (!lastTime && !leading) lastTime = nowTime;const remainTime = interval - (nowTime - lastTime);if (remainTime <= 0) {if (timer) {clearTimeout(timer);timer = null;}const result = fn.apply(this, args);if (resultCallback) resultCallback(result);resolve(result);lastTime = nowTime;return;}if (trailing && !timer) {timer = setTimeout(() => {timer = null;lastTime = !leading ? 0 : new Date().getTime();const result = fn.apply(this, args);if (resultCallback) resultCallback(result);resolve(result);}, remainTime);}});};_throttle.cancel = function() {if (timer) clearTimeout(timer);timer = null;lastTime = 0;};return _throttle;
}
</script>
<style scoped>
.slide-verify {position: relative;
}/* 图片加载样式 */
.slider-verify-loading {position: absolute;top: 0;right: 0;left: 0;bottom: 0;background: rgba(255, 255, 255, 0.9);z-index: 999;animation: loading 1.5s infinite;
}@keyframes loading {0% {opacity: 0.7;}100% {opacity: 9;}
}.slide-verify-block {position: absolute;left: 0;top: 0;
}.slide-verify-refresh-icon {position: absolute;right: 0;top: 0;width: 34px;height: 34px;cursor: pointer;background: url("../assets/icon_light.png") 0 -437px;background-size: 34px 471px;
}.slide-verify-slider {position: relative;text-align: center;width: 100%;height: 40px;line-height: 40px;margin-top: 15px;background: #f7f9fa;color: #45494c;border: 1px solid #e4e7eb;
}.slide-verify-slider-mask {position: absolute;left: 0;top: 0;height: 40px;border: 0 solid #1991fa;background: #d1e9fe;
}.slide-verify-slider-mask-item {position: absolute;top: 0;left: 0;width: 40px;height: 40px;background: #fff;box-shadow: 0 0 3px rgba(0, 0, 0, 0.3);cursor: pointer;transition: background 0.2s linear;
}.slide-verify-slider-mask-item:hover {background: #1991fa;
}.slide-verify-slider-mask-item:hover .slide-verify-slider-mask-item-icon {background-position: 0 -13px;
}.slide-verify-slider-mask-item-icon {position: absolute;top: 15px;left: 13px;width: 14px;height: 12px;background: url("../assets/icon_light.png") 0 -26px;background-size: 34px 471px;
}
.container-active .slide-verify-slider-mask-item {height: 38px;top: -1px;border: 1px solid #1991fa;
}.container-active .slide-verify-slider-mask {height: 38px;border-width: 1px;
}.container-success .slide-verify-slider-mask-item {height: 38px;top: -1px;border: 1px solid #52ccba;background-color: #52ccba !important;
}.container-success .slide-verify-slider-mask {height: 38px;border: 1px solid #52ccba;background-color: #d2f4ef;
}.container-success .slide-verify-slider-mask-item-icon {background-position: 0 0 !important;
}.container-fail .slide-verify-slider-mask-item {height: 38px;top: -1px;border: 1px solid #f57a7a;background-color: #f57a7a !important;
}.container-fail .slide-verify-slider-mask {height: 38px;border: 1px solid #f57a7a;background-color: #fce1e1;
}.container-fail .slide-verify-slider-mask-item-icon {top: 14px;background-position: 0 -82px !important;
}.container-active .slide-verify-slider-text,
.container-success .slide-verify-slider-text,
.container-fail .slide-verify-slider-text {display: none;
}
</style>

        基于slide-verify.vue创建组件,index.js代码如下:

import SlideVerify from './slide-verify.vue'const plugins = {install(Vue) {Vue.component(SlideVerify.name, SlideVerify)}
}if (typeof window !== 'undefined' && window.Vue) {window.Vue.use(SlideVerify)
}export default plugins

二、在项目中使用验证码

        在main.js中应用:

import { createApp } from 'vue'
import App from './App.vue'
// 导入验证码
import SlideVerify from './xxx/index'const vue = createApp(App)
vue.use(SlideVerify) // 在vue中使用
vue.mount('#app')

        准备验证码图片:

         其中icon_light.png图标图片如下,其他img.jpg图片可以是任意图片。

        在vue中使用验证码,App.vue代码如下:

<template><div id="app"><slide-verify ref="slideBlock" @success="onSuccess" @again="onAgain" @fulfilled="onFulfilled" @fail="onFail"@refresh="onRefresh" :slider-text="text" :imgs="imgs" :accuracy="accuracy"></slide-verify><div>{{ msg }}</div><button class="btn" @click="handleClick">在父组件点击刷新</button></div>
</template><script setup>
import img0 from './assets/img.jpg';
import img1 from './assets/img1.jpg';
import img2 from './assets/img2.jpg';
import img3 from './assets/img3.jpg';
import img4 from './assets/img4.jpg';
import img5 from './assets/img5.jpg';
import {ref} from "vue";const slideBlock = ref();
const msg = ref('');
const text = ref('向右滑动->');
const imgs = ref([img0,img1,img2,img3,img4,img5,
]);
const accuracy = ref(1); // 精确度小,可允许的误差范围小;为1时,则表示滑块要与凹槽完全重叠,才能验证成功。默认值为5const onSuccess = (times) => {console.log('验证通过');msg.value = `login success, 耗时${(times / 1000).toFixed(1)}s`;
};
const onFail = () => {console.log('验证不通过');msg.value = ''
};
const onRefresh = () => {console.log('点击了刷新小图标');msg.value = ''
};
const onFulfilled = () => {console.log('刷新成功啦!');
};
const onAgain = () => {console.log('检测到非人为操作的哦!');msg.value = 'try again';// 刷新handleClick();
};
const handleClick = () => {slideBlock.value.reset();msg.value = ''
}</script><style scoped>
#app {font-family: 'Avenir', Helvetica, Arial, sans-serif;-webkit-font-smoothing: antialiased;-moz-osx-font-smoothing: grayscale;color: #2c3e50;margin-top: 60px;
}.btn {margin-top: 20px;outline: 0;border: none;padding: 8px 15px;border-radius: 5px;color: #fff;background-color: #1890ff;cursor: pointer;
}.btn:active {box-shadow: 1px 5px 0 rgba(0, 0, 0, 0.1) inset;
}
</style>

        运行项目查看:

相关文章:

基于Vue的验证码实现

一、验证码核心实现 创建slide-verify.vue&#xff0c;代码如下&#xff1a; <template><divclass"slide-verify":style"{ width: w px }"id"slideVerify"onselectstart"return false;"><!-- 图片加载遮蔽罩 -->&…...

P4【力扣217,389,496】【数据结构】【哈希表】C++版

【217】存在重复元素 给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 &#xff0c;返回 true &#xff1b;如果数组中每个元素互不相同&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3,1] 输出&#xff1a;true 示例 2&#xff1a;…...

PE文件(六)新增节-添加代码作业

一.手动新增节添加代码 1.当预备条件都满足&#xff0c;节表结尾没有相关数据时&#xff1a; 现在我们将ipmsg.exe用winhex打开&#xff0c;在节的最后新增一个节用于存放我们要增加的数据 注意&#xff1a;飞鸽的文件对齐和内存对齐是一致的 先判断节表末尾到第一个节之间…...

ICRA 2024: NVIDIA 联合多伦多大学、加州大学伯克利分校、苏黎世联邦理工学院等研究人员开发了精细操作的手术机器人

英伟达&#xff08;NVIDIA&#xff09;正与学术研究人员合作&#xff0c;研究手术机器人。 NVIDIA 联合多伦多大学、加州大学伯克利分校、苏黎世联邦理工学院和佐治亚理工学院的研究人员开发了 ORBIT-Surgical&#xff0c;一个训练机器人的模拟框架&#xff0c;可以提高手术团…...

探索Go语言的原子操作秘籍:sync/atomic.Value全解析

引言 ​ 在并发编程的世界里&#xff0c;数据的一致性和线程安全是永恒的话题。Go语言以其独特的并发模型——goroutine和channel&#xff0c;简化了并发编程的复杂性。然而&#xff0c;在某些场景下&#xff0c;我们仍然需要一种机制来保证操作的原子性。这就是sync/atomic.V…...

【java深入学习第3章】利用 Spring Boot 和 Screw 快速生成数据库设计文档

免费多模型AI网站,支持豆包、GPT-4o、谷歌Gemini等AI模型&#xff0c;无限制使用&#xff0c;快去白嫖&#x1f449;海鲸AI&#x1f525;&#x1f525;&#x1f525; 在开发过程中&#xff0c;数据库设计文档是非常重要的&#xff0c;它可以帮助开发者理解数据库结构&#xff0…...

继“三级淋巴结”之后,再看看“单细胞”如何与AI结合【医学AI|顶刊速递|05-25】

小罗碎碎念 24-05-25文献速递 今天想和大家分享的是肿瘤治疗领域的另一个热点——单细胞技术&#xff0c;我们一起来看看&#xff0c;最新出炉的顶刊&#xff0c;是如何把AI与单细胞结合起来的。 另外&#xff0c;今天是周末&#xff0c;所以会有两篇文章——一篇文献速递&…...

[图解]产品经理创新之阿布思考法

0 00:00:00,000 --> 00:00:01,900 那刚才我们讲到了 1 00:00:02,730 --> 00:00:03,746 业务序列图 2 00:00:03,746 --> 00:00:04,560 然后怎么 3 00:00:05,530 --> 00:00:06,963 画现状&#xff0c;怎么改进 4 00:00:06,963 --> 00:00:09,012 然后改进的模式…...

Proteus仿真小技巧(隔空连线)

用了好几天Proteus了.总结一下使用的小技巧. 目录 一.隔空连线 1.打开添加网络标号 2.输入网络标号 二.常用元件 三.运行仿真 四.总结 一.隔空连线 引出一条线,并在末尾点一下. 1.打开添加网络标号 选择添加网络标号, 也可以先点击按钮,再去选择线(注意不要点端口) 2.…...

抖音极速版:抖音轻量精简版本,新人享大福利

和快手一样&#xff0c;抖音也有自己的极速版&#xff0c;可视作抖音的轻量精简版&#xff0c;更专注于刷视频看广告赚钱&#xff0c;收益比抖音要高&#xff0c;可玩性更佳。 抖音极速版简介 抖音极速版是一个提供短视频创业和收益任务的平台&#xff0c;用户可以通过观看广…...

leetCode-hot100-数组专题之双指针

数组双指针专题 1.同向双指针1.1例题26.删除有序数组中的重复项27.移除元素80.删除有序数组中的重复项 Ⅱ 2.相向双指针2.1例题11.盛最多水的容器42.接雨水581.最短无序连续子数组 双指针在算法题中很常见&#xff0c;下面总结双指针在数组中的一些应用&#xff0c;主要分为两类…...

完成商品SPU管理页面

文章目录 1.引入前端界面1.将前端界面放到commodity下2.创建菜单3.进入前端项目&#xff0c;使用npm添加依赖1.根目录下输入2.报错 chromedriver2.27.2的问题3.点击链接下载压缩包&#xff0c;然后使用下面的命令安装4.再次安装 pubsub-js 成功5.在main.js中引入这个组件 4.修改…...

Ansible实战YAML语言完成apache的部署,配置,启动全过程

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f3dd;️Ansible专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年5月24日15点59分 目录 &#x1f4af;趣站推荐&#x1f4af; &#x1f38a;前言 ✨️YAML语言回顾 &#x1f386;1.编写YAML文…...

深入探索微软Edge:新一代浏览器的演进与创新

在数字时代的浪潮中&#xff0c;浏览器已不再只是简单的网页访问工具&#xff0c;而是成为了连接信息、服务与用户之间的重要桥梁。微软Edge作为微软公司推出的一款全新的浏览器&#xff0c;不仅承载着微软在互联网领域的最新愿景&#xff0c;还融合了多项前沿技术&#xff0c;…...

k8s使用Volcano调度gpu

k8s部署 https://www.yangxingzhen.com/9817.html cri-dockerd安装 https://zhuanlan.zhihu.com/p/632861515 安装nvidia-container-runtime https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html 安装k8s-device-plugin https://…...

x的平方根-力扣

本题想到使用二分法不断逼近一个区间&#xff0c;直到最后趋近于x&#xff0c;从而求得解。注意的点&#xff0c;一开始使用 if(mid * mid < x) 进行判断时&#xff0c;会出现越界&#xff0c;原因是输入一个很大的数是&#xff0c;超过int表示的范围&#xff0c;继而修改为…...

hot100 -- 回溯(上)

目录 &#x1f35e;科普 &#x1f33c;全排列 AC DFS &#x1f6a9;子集 AC DFS &#x1f382;电话号码的字母组合 AC DFS &#x1f33c;组合总和 AC DFS &#x1f35e;科普 忘记 dfs 的&#xff0c;先看看这个&#x1f447; DFS&#xff08;深度优先搜索&#xf…...

5.24数据库作业

考虑如下关系模式R(A,B.C.D,E,F)上的函数依赖集F: {A→BCD&#xff0c;BC→DE&#xff0c;B→D&#xff0c;D→A} 1、计算B的闭包。 2、(使用Armstrong公理)证明AF是超码。 3、计算上述函数依赖集F的正则覆盖&#xff1b;给出你的推导的步骤并解释。 4、基于正则覆盖&#xff0…...

go-zero 实战(5)

引入Prometheus 用 Prometheus 监控应用 1. 用 docker 启动 Prometheus 编辑配置位置&#xff0c;我将 prometheus.yaml 和 targets.json 文件放在了 /opt/prometheus/conf目录下 prometheus.yaml global:scrape_interval: 15s # 抓取间隔evaluation_interval: 15s # 评估…...

Python异常处理:打造你的代码防弹衣!

Hi&#xff0c;我是阿佑&#xff0c;上文咱们讲到——揭秘Python的魔法&#xff1a;装饰器的超能力大揭秘 ‍♂️✨&#xff0c;阿佑将带领大家通过精准捕获异常、使用with语句和上下文管理器、以及异常链等高级技巧来增强代码的健壮性。就像为代码穿上防弹衣&#xff0c;保护它…...

[特殊字符] 智能合约中的数据是如何在区块链中保持一致的?

&#x1f9e0; 智能合约中的数据是如何在区块链中保持一致的&#xff1f; 为什么所有区块链节点都能得出相同结果&#xff1f;合约调用这么复杂&#xff0c;状态真能保持一致吗&#xff1f;本篇带你从底层视角理解“状态一致性”的真相。 一、智能合约的数据存储在哪里&#xf…...

树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法

树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源&#xff1a; http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作&#xff0c;无需更改相机配置。但是&#xff0c;一…...

iPhone密码忘记了办?iPhoneUnlocker,iPhone解锁工具Aiseesoft iPhone Unlocker 高级注册版​分享

平时用 iPhone 的时候&#xff0c;难免会碰到解锁的麻烦事。比如密码忘了、人脸识别 / 指纹识别突然不灵&#xff0c;或者买了二手 iPhone 却被原来的 iCloud 账号锁住&#xff0c;这时候就需要靠谱的解锁工具来帮忙了。Aiseesoft iPhone Unlocker 就是专门解决这些问题的软件&…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

如何为服务器生成TLS证书

TLS&#xff08;Transport Layer Security&#xff09;证书是确保网络通信安全的重要手段&#xff0c;它通过加密技术保护传输的数据不被窃听和篡改。在服务器上配置TLS证书&#xff0c;可以使用户通过HTTPS协议安全地访问您的网站。本文将详细介绍如何在服务器上生成一个TLS证…...

从零实现STL哈希容器:unordered_map/unordered_set封装详解

本篇文章是对C学习的STL哈希容器自主实现部分的学习分享 希望也能为你带来些帮助~ 那咱们废话不多说&#xff0c;直接开始吧&#xff01; 一、源码结构分析 1. SGISTL30实现剖析 // hash_set核心结构 template <class Value, class HashFcn, ...> class hash_set {ty…...

什么是EULA和DPA

文章目录 EULA&#xff08;End User License Agreement&#xff09;DPA&#xff08;Data Protection Agreement&#xff09;一、定义与背景二、核心内容三、法律效力与责任四、实际应用与意义 EULA&#xff08;End User License Agreement&#xff09; 定义&#xff1a; EULA即…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

Go 并发编程基础:通道(Channel)的使用

在 Go 中&#xff0c;Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式&#xff0c;用于在多个 Goroutine 之间传递数据&#xff0c;从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)

目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 &#xff08;1&#xff09;输入单引号 &#xff08;2&#xff09;万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...