版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
第C#滑動驗證碼拼圖驗證功能實現(xiàn)(SlideCaptcha)目錄使用背景:實現(xiàn)分析:后端代碼:準(zhǔn)備:使用:前端代碼:結(jié)語:
使用背景:
關(guān)于滑動驗證碼的使用場所還是非常多的,如:調(diào)取短信接口之前,和注冊請求之前或者頻繁會調(diào)用的接口都需要加這個拼圖驗證。這里先上一下效果圖吧(心中無碼,自然高清)。
話不多說,開擼!
實現(xiàn)分析:
滑動驗證碼的邏輯也很簡單。大概說一下:
1,服務(wù)器生成主圖+附圖(從主圖裁剪下來的不需要管y坐標(biāo))并且存儲X坐標(biāo);
2,前端傳入本地X坐標(biāo)到服務(wù)器。
3,服務(wù)器進(jìn)行計算存儲X坐標(biāo)和本地X坐標(biāo)相差值;
4,驗證相差值是否在0-2之間,判斷true|false
后端代碼:
準(zhǔn)備:
增加SlideCaptcha文件夾,并且增加Captcha.csCaptchaModel.csConfig.csImgFormat.cs4個文件。分別是:驗證,驗證實體,配置和圖片生成類。代碼如下:
Captcha.cs
usingSystem;
usingSystem.Drawing;
usingSystem.Drawing.Drawing2D;
usingSystem.Drawing.Imaging;
usingSystem.IO;
usingSystem.Net;
namespaceSliderCaptcha.NET
publicclassCaptcha
publicstaticCaptcha64ModelGenerateBase64()
CaptchaModelmodel=Captcha.Generate();
if(model!=null)
returnnewCaptcha64Model()
X=model.X,
Y=model.Y,
Background=ImageToBase64(model.Background,ImageFormat.Jpeg),
Slide=ImageToBase64(model.Slide,ImageFormat.Png)
else
returnnull;
///summary
///生成驗證碼
////summary
///returns/returns
publicstaticCaptchaModelGenerate()
Bitmapimage=BgImage();
if(image!=null)
intl=Config.l;
intd=Config.d;
intwidth=image.Width;
intheight=image.Height;
intx=RandomNext(width/3,width-d-l-10);//初始x
inty=RandomNext(10+d,height-l-10);;//初始y
GraphicsPathpath=GetSliderPath(x,y);
Graphicsg=GetGraphics(image);
//水印
if(Config.showWatermark)
Fontfont=newFont("宋體",12,FontStyle.Bold);
SizeFsize=g.MeasureString(Config.watermarkText,font);
PointPlogo=newPoint((int)(width-size.Width-5),(int)(height-size.Height-5));
Colorcolor=image.GetPixel(Plogo.X,Plogo.Y);
SolidBrushbru=newSolidBrush(AntiColor(color));
g.DrawString(Config.watermarkText,font,bru,Plogo);
Penpen=newPen(Color.FromArgb(200,255,255,255),2);
g.DrawPath(pen,path);
Imageslider=CaptureSlider(image,path,x,width,height);
SolidBrushbrush=newSolidBrush(Color.FromArgb(100,255,255,255));
g.FillPath(brush,path);
g.Save();
g.Dispose();
returnnewCaptchaModel()
X=x,
Y=y,
Background=image,
Slide=slider
returnnull;
///summary
///獲取圖片Graphics
////summary
///paramname="image"/param
///returns/returns
privatestaticGraphicsGetGraphics(Imageimage)
Graphicsg=Graphics.FromImage(image);
g.SmoothingMode=SmoothingMode.HighQuality;
g.CompositingQuality=CompositingQuality.HighQuality;
g.InterpolationMode=InterpolationMode.High;
returng;
///summary
///獲取滑塊path
////summary
privatestaticGraphicsPathGetSliderPath(intx,inty)
intl=Config.l;
intr=Config.r;
intb=Config.b;
intc=Config.c;
intd=Config.d;
intblod=Config.blod;
GraphicsPathpath=newGraphicsPath(FillMode.Winding);
PointPa=newPoint(x,y);
PointPb=newPoint(x+l/2-b,y-c+blod);
PointPd=newPoint(x+l,y);
PointPe=newPoint(Pd.X+c-blod,y+l/2-b);
PointPg=newPoint(Pd.X,y+l);
PointPh=newPoint(x,y+l);
PointPj=newPoint(x+c-blod,Pe.Y);
path.AddLine(Pa,Pb);
path.AddArc(x+l/2-r,y-d,d,d,130f,280f);
path.AddLines(newPoint[]{Pd,Pe});
path.AddArc(x+l,y+l/2-r,d,d,220f,280f);
path.AddLines(newPoint[]{Pg,Ph});
path.AddArc(x,y+l/2-r,d,d,140f,-280f);
path.AddLine(Pj,Pa);
returnpath;
///summary
///獲取滑塊區(qū)域
////summary
///paramname="image"/param
///paramname="path"/param
///paramname="x"/param
///paramname="width"/param
///paramname="height"/param
///returns/returns
privatestaticImageCaptureSlider(Imageimage,GraphicsPathpath,intx,intwidth,intheight)
Bitmapconcave=newBitmap(image.Width,image.Height);
Graphicsg=GetGraphics(concave);
TextureBrushbrush=newTextureBrush(image);
g.Clear(Color.Transparent);
g.FillPath(brush,path);
g.Dispose();
returnCaptureImage(concave,x,height);
///summary
///裁剪圖片
////summary
///paramname="fromImage"/param
///paramname="offsetX"/param
///paramname="width"/param
///paramname="height"/param
///returns/returns
privatestaticImageCaptureImage(ImagefromImage,intoffsetX,intheight)
intwidth=Config.l+Config.d+Config.blod;
Bitmapbitmap=newBitmap(width,height);
Graphicsg=GetGraphics(bitmap);
g.DrawImage(fromImage,0,0,newRectangle(offsetX,0,width,height),GraphicsUnit.Pixel);
g.Dispose();
returnbitmap;
///summary
///生成隨機數(shù)
////summary
///paramname="min"/param
///paramname="max"/param
///returns/returns
privatestaticintRandomNext(intmin,intmax)
Randomrandom=newRandom(Guid.NewGuid().GetHashCode());
returnrandom.Next(min,max);
///summary
///取反色
////summary
///paramname="color"/param
///returns/returns
publicstaticColorAntiColor(Colorcolor)
if(color.R128color.G128color.B128)
returnColor.Black;
else
returnColor.White;
///summary
///獲取背景圖
////summary
///returns/returns
privatestaticBitmapBgImage()
WebClientweb=newWebClient();
intnum=RandomNext(1,20);
Streamstream=web.OpenRead($"http://00/images/Pic/{num}.jpg");
Bitmapbitmap=(Bitmap)Image.FromStream(stream);
returnbitmap;
///summary
///base64轉(zhuǎn)圖片
////summary
///paramname="base64string"/param
///returns/returns
publicstaticBitmapBase64ToImage(stringbase64string)
byte[]b=Convert.FromBase64String(base64string);
MemoryStreamms=newMemoryStream(b);
Bitmapbitmap=newBitmap(ms);
returnbitmap;
///summary
///圖片轉(zhuǎn)base64
////summary
///paramname="image"/param
///returns/returns
publicstaticstringImageToBase64(Imageimage,ImageFormatformat)
if(image==null)returnstring.Empty;
stringstrbaser64="";
stringhead="";
stringformatName=ImgFormat.NameFromGuid(format);
head=$"data:image/{formatName.ToLower()};base64,";
MemoryStreamms=newMemoryStream();
image.Save(ms,format);
byte[]arr=newbyte[ms.Length];
ms.Position=0;
ms.Read(arr,0,(int)ms.Length);
ms.Close();
strbaser64=head+Convert.ToBase64String(arr);
catch(Exception)
thrownewException("Somethingwrongduringconvert!");
returnstrbaser64;
}
CaptchaModel.cs
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Drawing;
usingSystem.Linq;
usingSystem.Text;
namespaceSliderCaptcha.NET
publicclassCaptchaModel
publicintX{get;set;}
publicintY{get;set;}
publicImageBackground{get;set;}
publicImageSlide{get;set;}
publicclassCaptcha64Model
publicintX{get;set;}
publicintY{get;set;}
publicstringBackground{get;set;}
publicstringSlide{get;set;}
}
usingSystem;
namespaceSliderCaptcha.NET
publicclassConfig
///summary
///矩形寬
////summary
publicstaticintl=42;
///summary
///圓形半徑
////summary
publicstaticintr=9;
///summary
///圓形直徑
////summary
publicstaticintd=r*2;
///summary
///計算圓形與矩形交接三角形邊
////summary
publicstaticinta=(int)(r*Math.Sin(Math.PI*(50/180f)));
publicstaticintb=(int)(r*Math.Cos(Math.PI*(50/180f)));
publicstaticintc=r-a;
///summary
///滑塊邊框
////summary
publicstaticintblod=2;
///summary
///水印
////summary
publicstaticstringwatermarkText="SC.NET";
///summary
///是否顯示水印
////summary
publicstaticboolshowWatermark=true;
}
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Drawing.Imaging;
namespaceSliderCaptcha.NET
publicclassImgFormat
privatestaticDictionarystring,stringFormats=newDictionarystring,string(){
{"b96b3caa-0728-11d3-9d7b-0000f81ef32e","MemoryBmp"},
{"b96b3cab-0728-11d3-9d7b-0000f81ef32e","Bmp"},
{"b96b3cac-0728-11d3-9d7b-0000f81ef32e","Emf"},
{"b96b3cad-0728-11d3-9d7b-0000f81ef32e","Wmf"},
{"b96b3cae-0728-11d3-9d7b-0000f81ef32e","Jpeg"},
{"b96b3caf-0728-11d3-9d7b-0000f81ef32e","Png"},
{"b96b3cb0-0728-11d3-9d7b-0000f81ef32e","Gif"},
{"b96b3cb1-0728-11d3-9d7b-0000f81ef32e","Tiff"},
{"b96b3cb2-0728-11d3-9d7b-0000f81ef32e","Exif"},
{"b96b3cb5-0728-11d3-9d7b-0000f81ef32e","Icon"}
publicstaticImageFormatFormatFromGuid(ImageFormatformat)
returnFormatFromGuid(format.Guid);
publicstaticImageFormatFormatFromGuid(Guidguid)
returnFormatFromGuid(guid.ToString());
publicstaticImageFormatFormatFromGuid(stringguid)
if(Formats.ContainsKey(guid))
stringname=Formats[guid];
ImageFormatformat=null;
switch(name)
case"MemoryBmp":
format=ImageFormat.MemoryBmp;
break;
case"Bmp":
format=ImageFormat.Bmp;
break;
case"Emf":
format=ImageFormat.Emf;
break;
case"Wmf":
format=ImageFormat.Wmf;
break;
case"Gif":
format=ImageFormat.Gif;
break;
case"Jpeg":
format=ImageFormat.Jpeg;
break;
case"Png":
format=ImageFormat.Png;
break;
case"Tiff":
format=ImageFormat.Tiff;
break;
case"Exif":
format=ImageFormat.Exif;
break;
case"Icon":
format=ImageFormat.Icon;
break;
returnformat;
else
returnnull;
publicstaticstringNameFromGuid(ImageFormatformat)
returnNameFromGuid(format.Guid);
publicstaticstringNameFromGuid(Guidguid)
returnNameFromGuid(guid.ToString());
publicstaticstringNameFromGuid(stringguid)
if(Formats.ContainsKey(guid))
returnFormats[guid];
else
returnstring.Empty;
}
使用:
這里用的是mvc的框架,用的是api接口,前后端分離供前端使用。具體使用根據(jù)個人需求,可以是接口調(diào)用亦可以是項目調(diào)用。
呼聲如果很高的話,考慮出一個winfrom版本的滑動驗證碼~(滑稽)
[HttpGet]
publicIHttpActionResultGetCaptcha()
Captcha64Modelmodel=Captcha.GenerateBase64();
CacheHelper.Cache.SetCache("sliderX",model.X);
Hashtableht=newHashtable();
ht.Add("background",model.Background);
ht.Add("slider",model.Slide);
ht.Add("sliderXXXXX",model.X);
returnJson(ht);
///summary
///檢查驗證
////summary
///paramname="x"/param
///returns/returns
[HttpPost]
publicIHttpActionResultCheckCaptcha([FromBody]intx=0)
Hashtablehs=newHashtable();
stringMess="";
intCode=0;
varsession=CacheHelper.Cache.GetCache("sliderX");
if(session==null)
Mess="請刷新驗證碼";
Code=500;
gotoblock;
stringsliderXStr=session.ToString();//asstring
intsliderX=Convert.ToInt32(sliderXStr);
intdifX=sliderX-x;
if(difX=0-Config.bloddifX=Config.blod)
Mess="success";
Code=0;
else
session=null;
Mess="錯誤";
Code=500;
block:
hs.Add("Mess",Mess);
hs.Add("Code",Code);
returnJson(hs);
}
前端代碼:
!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.0Transitional//EN"
html
head
titleSplideCaptcha/title
style
-webkit-user-select:none;
-moz-user-select:none;
-ms-user-select:none;
user-select:none;
.sc-captcha{
width:300px;
margin:100pxauto;
.sc_net_panel{
padding:10px;
.sc_net_paneldiv{
position:relative;
.bg_slider{
position:absolute;
left:0;
top:0;
.bg_refresh{
position:absolute;
right:5px;
top:5px;
background:#808080;
color:#fff;
border-radius:3px;
width:16px;
line-height:16px;
text-align:center;
cursor:pointer;
.sc_net_slider_icon{
position:absolute;
left:0;
top:0;
height:37px;
text-align:center;
border-radius:5px;
border:#8080801pxsolid;
width:37px;
line-height:37px;
cursor:pointer;
.sc_net_slider_icon:hover{
color:#fff;
background:#1991fa;
.sc_net_slider_text{
position:absolute;
left:0;
top:0;
text-align:center;
width:280px;
color:#45494c;
border:#8080801pxsolid;
border-radius:5px;
line-height:35px;
height:37px;
cursor:default;
.sc_net_slider_area{
position:absolute;
left:0;
top:0;
height:37px;
/style
scriptsrc="E:\porject\碚煜Api\ByzkApi\Scripts\jquery-3.4.1.js"/script
scriptsrc="E:\porject\碚煜Api\ByzkApi\Scripts\jquery-3.4.1.min.js"/script
/head
body
div
div
div
div
div
/div
divtitle="刷新"?/div
/div
/div
div
div
div向右拖動滑塊填充拼圖/div
div/div
div?/div
/div
/div
/div
/div
/body
script
loadCaptcha();
functionloadCaptcha(){
$.ajax({
url:"16:5500/api/TestApi/GetCaptcha",
type:"Get",
dataType:"JSON",
success:function(json){
varbg=createCanvas(280,155);
bg.className='bg_img';
bg_slider=createCanvas(62,155);
bg_slider.className='bg_slider';
CanvasSetImage(bg,json.background);
CanvasSetImage(bg_slider,json.slider);
vardoc=document.getElementsByClassName("sc_net_bgimg")[0];
doc.innerHTML="";
doc.appendChild(bg);
doc.appendChild(bg_slider);
console.log(json.modelX);
functioncreateCanvas(width,height){
varcanvas=document.createElement('canvas');
canvas.width=width;
canvas.height=height;
returncanvas;
functionCanvasSetImage(_canvas,base64){
//獲取2d畫布對象
varctx=_canvas.getContext("2d");
//創(chuàng)建圖片標(biāo)簽
var_img=document.createElement("img");
//設(shè)置圖片地址
_img.src=base64;
//ctx.fillRect(0,0,_canvas.clientWidth,_canvas.clientHeight);
//ctx.fillStyle='rgba(255,255,255,0)';
_img.onload=function(){
ctx.drawImage(_img,0,0);
/*ctx.drawImage(_img,10,10);*/
functiongetByClassName0(className){
returndocument.getElementsByClassName(className)[0];
varslider=getByClassName0("sc_net_slider_icon");
vartext=getByClassName0("sc_net_slider_text");
vararea=getByClassName0("sc_net_slider_area");
varbg_slider;
slider.addEventListener('mousedown',handleDragStart);
slider.addEventListener('touc
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 企業(yè)戰(zhàn)略規(guī)劃與執(zhí)行管理(標(biāo)準(zhǔn)版)
- 城市公共交通設(shè)施維護(hù)與管理手冊(標(biāo)準(zhǔn)版)
- 企業(yè)信息化培訓(xùn)管理手冊(標(biāo)準(zhǔn)版)
- 廢舊物資處置流程制度
- 企業(yè)信息化培訓(xùn)管理規(guī)范(標(biāo)準(zhǔn)版)
- 四川能投高縣綜合能源有限公司2025年招聘工作人員備考題庫及完整答案詳解1套
- 養(yǎng)老院工作人員培訓(xùn)考核評價制度
- 原平市2025年公開招聘社區(qū)專職工作人員備考題庫帶答案詳解
- 2026年瀘州市人民南路幼兒園招聘備考題庫及答案詳解1套
- 2026年閩南師范大學(xué)引進(jìn)高層次人才招聘97人備考題庫及一套答案詳解
- 2026年國安民警副科級面試題及實戰(zhàn)解答
- 2026年紀(jì)檢監(jiān)察室工作面試題集
- 浙江省紹興市諸暨市2024-2025學(xué)年四年級上冊期末考試數(shù)學(xué)試卷(含答案)
- 廣東省廣州市天河區(qū)2024-2025學(xué)年七年級上學(xué)期期末考試語文試題(含答案)
- 11340《古代小說戲曲專題》國家開放大學(xué)期末考試題庫
- 江蘇省淮安市淮陰區(qū)事業(yè)單位考試試題2025年附答案
- 服裝代運營協(xié)議書
- 對口升學(xué)考試綜合模擬試卷(第七版) 文化課綜合模擬試卷 參考答案
- 2025安徽省交通控股集團(tuán)有限公司六安中心招聘收費協(xié)管員24人考試筆試參考題庫附答案解析
- 2025年移動式壓力容器充裝R2作業(yè)證考試練習(xí)題庫及答案
- FSSC22000 V6食品安全管理體系管理手冊及程序文件
評論
0/150
提交評論