[原创]红马版验证码实现(中文+变形+噪点)
生活随笔
收集整理的這篇文章主要介紹了
[原创]红马版验证码实现(中文+变形+噪点)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
為了應付越來越多的自動發帖機、惡意攻擊等情形,驗證碼技術在大量的網站上得到使用。我在近期開發一個注冊網站的時候,也使用了這一技術。當然,我并不想完完全全自己重新實現,而是參考了網上能夠找到的實現,做了若干改進而已。下面談談我的實現。
??? 補兩張圖片:
??? ??
??? 首先看驗證碼圖片輸出頁的代碼:
<%@?Page?Language="C#"?%>
<!DOCTYPE?html?PUBLIC?"-//W3C//DTD?XHTML?1.0?Transitional//EN"?"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script?runat="server">
????protected?void?Page_Load(object?sender,?EventArgs?e)
????{
????????VryImgGen?gen?=?new?VryImgGen();
????????string?verifyCode?=?gen.CreateVerifyCode(5,?1);
????????Session["VerifyCode"]?=?verifyCode.ToUpper();
????????System.Drawing.Bitmap?bitmap?=?gen.CreateImage(verifyCode);
????????System.IO.MemoryStream?ms?=?new?System.IO.MemoryStream();
????????bitmap.Save(ms,?System.Drawing.Imaging.ImageFormat.Png);
????????Response.Clear();
????????Response.ContentType?=?"image/Png";
????????Response.BinaryWrite(ms.GetBuffer());
????????bitmap.Dispose();
????????ms.Dispose();
????????ms.Close();
????????Response.End();
????}
</script> ??? 功能很簡單,初始化一個驗證碼生成對象,生成圖片。然后保存到一個MemoryStream里。得到字節流,輸出字節流。驗證碼的數據是保存在Session中的,這是最簡單的方法?;蛘呖梢约用軆Υ嬖赾ookie里,也是可以的。
??? 再來看看驗證碼生成對象: using?System;
using?System.Data;
using?System.Configuration;
using?System.Web;
using?System.Web.Security;
using?System.Web.UI;
using?System.Web.UI.WebControls;
using?System.Web.UI.WebControls.WebParts;
using?System.Web.UI.HtmlControls;
using?System.Drawing;
using?System.Text;
///?<summary>
///?Summary?description?for?VryImgGen
///?</summary>
public?partial?class?VryImgGen
{
????
????///?<summary>
????///?供驗證碼生成漢字時選取的漢字集,若為空則按照《GB2312簡體中文編碼表》編碼規則構造漢字
????///?</summary>
????public?static?string?ChineseChars?=?String.Empty;
????///?<summary>
????///?英文與數字串
????///?</summary>
????protected?static?readonly?string?EnglishOrNumChars?=?"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
???
????public?VryImgGen()
????{
????????rnd?=?new?Random(unchecked((int)DateTime.Now.Ticks));
????}
????///?<summary>
????///?全局隨機數生成器
????///?</summary>
????private?Random?rnd;
????
????int?length?=?5;
????///?<summary>
????///?驗證碼長度(默認6個驗證碼的長度)
????///?</summary>
????public?int?Length
????{
????????get?{?return?length;?}
????????set?{?length?=?value;?}
????}
????????
????int?fontSize?=?18;
????///?<summary>
????///?驗證碼字體大小(為了顯示扭曲效果,默認30像素,可以自行修改)
????///?</summary>
????public?int?FontSize
????{
????????get?{?return?fontSize;?}
????????set?{?fontSize?=?value;?}
????}???
????
????int?padding?=?4;
????///?<summary>
????///?邊框補(默認4像素)
????///?</summary>
????public?int?Padding
????{
????????get?{?return?padding;?}
????????set?{?padding?=?value;?}
????}???
????
????bool?chaos?=?true;
????///?<summary>
????///?是否輸出燥點(默認輸出)
????///?</summary>
????public?bool?Chaos
????{
????????get?{?return?chaos;?}
????????set?{?chaos?=?value;?}
????}???
????????
????Color?chaosColor?=?Color.LightGray;
????///?<summary>
????///?輸出燥點的顏色(默認灰色)
????///?</summary>
????public?Color?ChaosColor
????{
????????get?{?return?chaosColor;?}
????????set?{?chaosColor?=?value;?}
????}
????
????Color?backgroundColor?=?Color.White;
????///?<summary>
????///?自定義背景色(默認白色)
????///?</summary>
????public?Color?BackgroundColor
????{
????????get?{?return?backgroundColor;?}
????????set?{?backgroundColor?=?value;?}
????}???
????????
????Color[]?colors?=?{?Color.Black,?Color.Red,?Color.DarkBlue,?Color.Green,?Color.Orange,?Color.Brown,?Color.DarkCyan,?Color.Purple?};
????///?<summary>
????///?自定義隨機顏色數組
????///?</summary>
????public?Color[]?Colors
????{
????????get?{?return?colors;?}
????????set?{?colors?=?value;?}
????}
??
????string[]?fonts?=?{?"Arial",?"Georgia"?};
????///?<summary>
????///?自定義字體數組
????///?</summary>
????public?string[]?Fonts
????{
????????get?{?return?fonts;?}
????????set?{?fonts?=?value;?}
????}???
????#region?產生波形濾鏡效果
????private?const?double?PI?=?3.1415926535897932384626433832795;
????private?const?double?PI2?=?6.283185307179586476925286766559;
????///?<summary>
????///?正弦曲線Wave扭曲圖片(Edit?By?51aspx.com)
????///?</summary>
????///?<param?name="srcBmp">圖片路徑</param>
????///?<param?name="bXDir">如果扭曲則選擇為True</param>
????///?<param?name="nMultValue">波形的幅度倍數,越大扭曲的程度越高,一般為3</param>
????///?<param?name="dPhase">波形的起始相位,取值區間[0-2*PI)</param>
????///?<returns></returns>
????public?System.Drawing.Bitmap?TwistImage(Bitmap?srcBmp,?bool?bXDir,?double?dMultValue,?double?dPhase)
????{
????????System.Drawing.Bitmap?destBmp?=?new?Bitmap(srcBmp.Width,?srcBmp.Height);
????????//?將位圖背景填充為白色
????????System.Drawing.Graphics?graph?=?System.Drawing.Graphics.FromImage(destBmp);
????????graph.FillRectangle(new?SolidBrush(System.Drawing.Color.White),?0,?0,?destBmp.Width,?destBmp.Height);
????????graph.Dispose();
????????double?dBaseAxisLen?=?bXDir???(double)destBmp.Height?:?(double)destBmp.Width;
????????for?(int?i?=?0;?i?<?destBmp.Width;?i++)
????????{
????????????for?(int?j?=?0;?j?<?destBmp.Height;?j++)
????????????{
????????????????double?dx?=?0;
????????????????dx?=?bXDir???(PI2?*?(double)j)?/?dBaseAxisLen?:?(PI2?*?(double)i)?/?dBaseAxisLen;
????????????????dx?+=?dPhase;
????????????????double?dy?=?Math.Sin(dx);
????????????????//?取得當前點的顏色
????????????????int?nOldX?=?0,?nOldY?=?0;
????????????????nOldX?=?bXDir???i?+?(int)(dy?*?dMultValue)?:?i;
????????????????nOldY?=?bXDir???j?:?j?+?(int)(dy?*?dMultValue);
????????????????System.Drawing.Color?color?=?srcBmp.GetPixel(i,?j);
????????????????if?(nOldX?>=?0?&&?nOldX?<?destBmp.Width
?????????????????&&?nOldY?>=?0?&&?nOldY?<?destBmp.Height)
????????????????{
????????????????????destBmp.SetPixel(nOldX,?nOldY,?color);
????????????????}
????????????}
????????}
????????return?destBmp;
????}
????#endregion
???
????///?<summary>
????///?生成校驗碼圖片
????///?</summary>
????///?<param?name="code">驗證碼</param>
????///?<returns></returns>
????public?Bitmap?CreateImage(string?code)
????{
????????int?fSize?=?FontSize;
????????int?fWidth?=?fSize?+?Padding;
????????int?imageWidth?=?(int)(code.Length?*?fWidth)?+?4?+?Padding?*?2;
????????int?imageHeight?=?fSize?*?2?+?Padding?*?2;
????????System.Drawing.Bitmap?image?=?new?System.Drawing.Bitmap(imageWidth,?imageHeight);
????????Graphics?g?=?Graphics.FromImage(image);
????????g.Clear(BackgroundColor);
????????//給背景添加隨機生成的燥點
????????if?(this.Chaos)
????????{
????????????Pen?pen?=?new?Pen(ChaosColor,?0);
????????????int?c?=?Length?*?10;
????????????for?(int?i?=?0;?i?<?c;?i++)
????????????{
????????????????int?x?=?rnd.Next(image.Width);
????????????????int?y?=?rnd.Next(image.Height);
????????????????g.DrawRectangle(pen,?x,?y,?1,?1);
????????????}
????????}
????????int?left?=?0,?top?=?0,?top1?=?1,?top2?=?1;
????????int?n1?=?(imageHeight?-?FontSize?-?Padding?*?2);
????????int?n2?=?n1?/?4;
????????top1?=?n2;
????????top2?=?n2?*?2;
????????Font?f;
????????Brush?b;
????????int?cindex,?findex;
????????//隨機字體和顏色的驗證碼字符
????????for?(int?i?=?0;?i?<?code.Length;?i++)
????????{
????????????cindex?=?rnd.Next(Colors.Length?-?1);
????????????findex?=?rnd.Next(Fonts.Length?-?1);
????????????f?=?new?System.Drawing.Font(Fonts[findex],?fSize,?System.Drawing.FontStyle.Bold);
????????????b?=?new?System.Drawing.SolidBrush(Colors[cindex]);
????????????if?(i?%?2?==?1)
????????????{
????????????????top?=?top2;
????????????}
????????????else
????????????{
????????????????top?=?top1;
????????????}
????????????left?=?i?*?fWidth;
????????????g.DrawString(code.Substring(i,?1),?f,?b,?left,?top);
????????}
????????//畫一個邊框?邊框顏色為Color.Gainsboro
????????g.DrawRectangle(new?Pen(Color.Gainsboro,?0),?0,?0,?image.Width?-?1,?image.Height?-?1);
????????g.Dispose();
????????//產生波形(Add?By?51aspx.com)
????????image?=?TwistImage(image,?true,?8,?4);
????????return?image;
????}
????????????
????///?<summary>
????///?生成隨機字符碼
????///?</summary>
????///?<param?name="codeLen">字符串長度</param>
????///?<param?name="zhCharsCount">中文字符數</param>
????///?<returns></returns>
????public?string?CreateVerifyCode(int?codeLen,?int?zhCharsCount)
????{
????????char[]?chs?=?new?char[codeLen];
????????int?index;
????????for?(int?i?=?0;?i?<?zhCharsCount;?i++)
????????{
????????????index?=?rnd.Next(0,?codeLen);
????????????if?(chs[index]?==?'\0')
????????????????chs[index]?=?CreateZhChar();
????????????else
????????????????--i;
????????}
????????for?(int?i?=?0;?i?<?codeLen;?i++)
????????{
????????????if?(chs[i]?==?'\0')
????????????????chs[i]?=?CreateEnOrNumChar();
????????}
????????return?new?string(chs,?0,?chs.Length);
????}
????///?<summary>
????///?生成默認長度5的隨機字符碼
????///?</summary>
????///?<returns></returns>
????public?string?CreateVerifyCode()
????{
????????return?CreateVerifyCode(Length,?0);
????}
????
????///?<summary>
????///?生成英文或數字字符
????///?</summary>
????///?<returns></returns>
????protected?char?CreateEnOrNumChar()
????{
????????return?EnglishOrNumChars[rnd.Next(0,?EnglishOrNumChars.Length)];
????}
????///?<summary>
????///?生成漢字字符
????///?</summary>
????///?<returns></returns>
????protected?char?CreateZhChar()
????{
????????//若提供了漢字集,查詢漢字集選取漢字
????????if?(ChineseChars.Length?>?0)
????????{
????????????return?ChineseChars[rnd.Next(0,?ChineseChars.Length)];
????????}
????????//若沒有提供漢字集,則根據《GB2312簡體中文編碼表》編碼規則構造漢字
????????else
????????{
????????????byte[]?bytes?=?new?byte[2];
????????????//第一個字節值在0xb0,?0xf7之間
????????????bytes[0]?=?(byte)rnd.Next(0xb0,?0xf8);
????????????//第二個字節值在0xa1,?0xfe之間
????????????bytes[1]?=?(byte)rnd.Next(0xa1,?0xff);
????????????//根據漢字編碼的字節數組解碼出中文漢字
????????????string?str1?=?Encoding.GetEncoding("gb2312").GetString(bytes);
????????????return?str1[0];
????????}
????}
}
??? 這里面大量使用了51aspx.com的代碼,在此表示感謝。這里的主要改進在于支持生成中英文混合的驗證碼。中文的生成有兩種方式,一是根據《GB2312簡體中文編碼表》編碼規則構造漢字,二是從一個選定的中文字符集合中隨即選取漢字。實現很簡單,參考函數protected?char?CreateZhChar(),在此不贅述。
??? 最后說一下驗證碼的使用,下面是一個例子:??
<img?src="VerifyCode.aspx"?id="valiCode"?alt="驗證碼"?/>
<a?title="刷新驗證碼"?href="#"?onclick="javascript:document.getElementById('valiCode').src='VerifyCode.aspx?id='+Math.random();return?false;">看不清,換張圖片?</a> ??? 這里有個小技巧,就是在刷新驗證碼的使用,驗證碼的URL后面用了隨機參數以欺騙瀏覽器重新請求。
源代碼
2500常用漢字
498常用漢字
??? 補兩張圖片:
??? ??
??? 首先看驗證碼圖片輸出頁的代碼:
<%@?Page?Language="C#"?%>
<!DOCTYPE?html?PUBLIC?"-//W3C//DTD?XHTML?1.0?Transitional//EN"?"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script?runat="server">
????protected?void?Page_Load(object?sender,?EventArgs?e)
????{
????????VryImgGen?gen?=?new?VryImgGen();
????????string?verifyCode?=?gen.CreateVerifyCode(5,?1);
????????Session["VerifyCode"]?=?verifyCode.ToUpper();
????????System.Drawing.Bitmap?bitmap?=?gen.CreateImage(verifyCode);
????????System.IO.MemoryStream?ms?=?new?System.IO.MemoryStream();
????????bitmap.Save(ms,?System.Drawing.Imaging.ImageFormat.Png);
????????Response.Clear();
????????Response.ContentType?=?"image/Png";
????????Response.BinaryWrite(ms.GetBuffer());
????????bitmap.Dispose();
????????ms.Dispose();
????????ms.Close();
????????Response.End();
????}
</script> ??? 功能很簡單,初始化一個驗證碼生成對象,生成圖片。然后保存到一個MemoryStream里。得到字節流,輸出字節流。驗證碼的數據是保存在Session中的,這是最簡單的方法?;蛘呖梢约用軆Υ嬖赾ookie里,也是可以的。
??? 再來看看驗證碼生成對象: using?System;
using?System.Data;
using?System.Configuration;
using?System.Web;
using?System.Web.Security;
using?System.Web.UI;
using?System.Web.UI.WebControls;
using?System.Web.UI.WebControls.WebParts;
using?System.Web.UI.HtmlControls;
using?System.Drawing;
using?System.Text;
///?<summary>
///?Summary?description?for?VryImgGen
///?</summary>
public?partial?class?VryImgGen
{
????
????///?<summary>
????///?供驗證碼生成漢字時選取的漢字集,若為空則按照《GB2312簡體中文編碼表》編碼規則構造漢字
????///?</summary>
????public?static?string?ChineseChars?=?String.Empty;
????///?<summary>
????///?英文與數字串
????///?</summary>
????protected?static?readonly?string?EnglishOrNumChars?=?"0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
???
????public?VryImgGen()
????{
????????rnd?=?new?Random(unchecked((int)DateTime.Now.Ticks));
????}
????///?<summary>
????///?全局隨機數生成器
????///?</summary>
????private?Random?rnd;
????
????int?length?=?5;
????///?<summary>
????///?驗證碼長度(默認6個驗證碼的長度)
????///?</summary>
????public?int?Length
????{
????????get?{?return?length;?}
????????set?{?length?=?value;?}
????}
????????
????int?fontSize?=?18;
????///?<summary>
????///?驗證碼字體大小(為了顯示扭曲效果,默認30像素,可以自行修改)
????///?</summary>
????public?int?FontSize
????{
????????get?{?return?fontSize;?}
????????set?{?fontSize?=?value;?}
????}???
????
????int?padding?=?4;
????///?<summary>
????///?邊框補(默認4像素)
????///?</summary>
????public?int?Padding
????{
????????get?{?return?padding;?}
????????set?{?padding?=?value;?}
????}???
????
????bool?chaos?=?true;
????///?<summary>
????///?是否輸出燥點(默認輸出)
????///?</summary>
????public?bool?Chaos
????{
????????get?{?return?chaos;?}
????????set?{?chaos?=?value;?}
????}???
????????
????Color?chaosColor?=?Color.LightGray;
????///?<summary>
????///?輸出燥點的顏色(默認灰色)
????///?</summary>
????public?Color?ChaosColor
????{
????????get?{?return?chaosColor;?}
????????set?{?chaosColor?=?value;?}
????}
????
????Color?backgroundColor?=?Color.White;
????///?<summary>
????///?自定義背景色(默認白色)
????///?</summary>
????public?Color?BackgroundColor
????{
????????get?{?return?backgroundColor;?}
????????set?{?backgroundColor?=?value;?}
????}???
????????
????Color[]?colors?=?{?Color.Black,?Color.Red,?Color.DarkBlue,?Color.Green,?Color.Orange,?Color.Brown,?Color.DarkCyan,?Color.Purple?};
????///?<summary>
????///?自定義隨機顏色數組
????///?</summary>
????public?Color[]?Colors
????{
????????get?{?return?colors;?}
????????set?{?colors?=?value;?}
????}
??
????string[]?fonts?=?{?"Arial",?"Georgia"?};
????///?<summary>
????///?自定義字體數組
????///?</summary>
????public?string[]?Fonts
????{
????????get?{?return?fonts;?}
????????set?{?fonts?=?value;?}
????}???
????#region?產生波形濾鏡效果
????private?const?double?PI?=?3.1415926535897932384626433832795;
????private?const?double?PI2?=?6.283185307179586476925286766559;
????///?<summary>
????///?正弦曲線Wave扭曲圖片(Edit?By?51aspx.com)
????///?</summary>
????///?<param?name="srcBmp">圖片路徑</param>
????///?<param?name="bXDir">如果扭曲則選擇為True</param>
????///?<param?name="nMultValue">波形的幅度倍數,越大扭曲的程度越高,一般為3</param>
????///?<param?name="dPhase">波形的起始相位,取值區間[0-2*PI)</param>
????///?<returns></returns>
????public?System.Drawing.Bitmap?TwistImage(Bitmap?srcBmp,?bool?bXDir,?double?dMultValue,?double?dPhase)
????{
????????System.Drawing.Bitmap?destBmp?=?new?Bitmap(srcBmp.Width,?srcBmp.Height);
????????//?將位圖背景填充為白色
????????System.Drawing.Graphics?graph?=?System.Drawing.Graphics.FromImage(destBmp);
????????graph.FillRectangle(new?SolidBrush(System.Drawing.Color.White),?0,?0,?destBmp.Width,?destBmp.Height);
????????graph.Dispose();
????????double?dBaseAxisLen?=?bXDir???(double)destBmp.Height?:?(double)destBmp.Width;
????????for?(int?i?=?0;?i?<?destBmp.Width;?i++)
????????{
????????????for?(int?j?=?0;?j?<?destBmp.Height;?j++)
????????????{
????????????????double?dx?=?0;
????????????????dx?=?bXDir???(PI2?*?(double)j)?/?dBaseAxisLen?:?(PI2?*?(double)i)?/?dBaseAxisLen;
????????????????dx?+=?dPhase;
????????????????double?dy?=?Math.Sin(dx);
????????????????//?取得當前點的顏色
????????????????int?nOldX?=?0,?nOldY?=?0;
????????????????nOldX?=?bXDir???i?+?(int)(dy?*?dMultValue)?:?i;
????????????????nOldY?=?bXDir???j?:?j?+?(int)(dy?*?dMultValue);
????????????????System.Drawing.Color?color?=?srcBmp.GetPixel(i,?j);
????????????????if?(nOldX?>=?0?&&?nOldX?<?destBmp.Width
?????????????????&&?nOldY?>=?0?&&?nOldY?<?destBmp.Height)
????????????????{
????????????????????destBmp.SetPixel(nOldX,?nOldY,?color);
????????????????}
????????????}
????????}
????????return?destBmp;
????}
????#endregion
???
????///?<summary>
????///?生成校驗碼圖片
????///?</summary>
????///?<param?name="code">驗證碼</param>
????///?<returns></returns>
????public?Bitmap?CreateImage(string?code)
????{
????????int?fSize?=?FontSize;
????????int?fWidth?=?fSize?+?Padding;
????????int?imageWidth?=?(int)(code.Length?*?fWidth)?+?4?+?Padding?*?2;
????????int?imageHeight?=?fSize?*?2?+?Padding?*?2;
????????System.Drawing.Bitmap?image?=?new?System.Drawing.Bitmap(imageWidth,?imageHeight);
????????Graphics?g?=?Graphics.FromImage(image);
????????g.Clear(BackgroundColor);
????????//給背景添加隨機生成的燥點
????????if?(this.Chaos)
????????{
????????????Pen?pen?=?new?Pen(ChaosColor,?0);
????????????int?c?=?Length?*?10;
????????????for?(int?i?=?0;?i?<?c;?i++)
????????????{
????????????????int?x?=?rnd.Next(image.Width);
????????????????int?y?=?rnd.Next(image.Height);
????????????????g.DrawRectangle(pen,?x,?y,?1,?1);
????????????}
????????}
????????int?left?=?0,?top?=?0,?top1?=?1,?top2?=?1;
????????int?n1?=?(imageHeight?-?FontSize?-?Padding?*?2);
????????int?n2?=?n1?/?4;
????????top1?=?n2;
????????top2?=?n2?*?2;
????????Font?f;
????????Brush?b;
????????int?cindex,?findex;
????????//隨機字體和顏色的驗證碼字符
????????for?(int?i?=?0;?i?<?code.Length;?i++)
????????{
????????????cindex?=?rnd.Next(Colors.Length?-?1);
????????????findex?=?rnd.Next(Fonts.Length?-?1);
????????????f?=?new?System.Drawing.Font(Fonts[findex],?fSize,?System.Drawing.FontStyle.Bold);
????????????b?=?new?System.Drawing.SolidBrush(Colors[cindex]);
????????????if?(i?%?2?==?1)
????????????{
????????????????top?=?top2;
????????????}
????????????else
????????????{
????????????????top?=?top1;
????????????}
????????????left?=?i?*?fWidth;
????????????g.DrawString(code.Substring(i,?1),?f,?b,?left,?top);
????????}
????????//畫一個邊框?邊框顏色為Color.Gainsboro
????????g.DrawRectangle(new?Pen(Color.Gainsboro,?0),?0,?0,?image.Width?-?1,?image.Height?-?1);
????????g.Dispose();
????????//產生波形(Add?By?51aspx.com)
????????image?=?TwistImage(image,?true,?8,?4);
????????return?image;
????}
????????????
????///?<summary>
????///?生成隨機字符碼
????///?</summary>
????///?<param?name="codeLen">字符串長度</param>
????///?<param?name="zhCharsCount">中文字符數</param>
????///?<returns></returns>
????public?string?CreateVerifyCode(int?codeLen,?int?zhCharsCount)
????{
????????char[]?chs?=?new?char[codeLen];
????????int?index;
????????for?(int?i?=?0;?i?<?zhCharsCount;?i++)
????????{
????????????index?=?rnd.Next(0,?codeLen);
????????????if?(chs[index]?==?'\0')
????????????????chs[index]?=?CreateZhChar();
????????????else
????????????????--i;
????????}
????????for?(int?i?=?0;?i?<?codeLen;?i++)
????????{
????????????if?(chs[i]?==?'\0')
????????????????chs[i]?=?CreateEnOrNumChar();
????????}
????????return?new?string(chs,?0,?chs.Length);
????}
????///?<summary>
????///?生成默認長度5的隨機字符碼
????///?</summary>
????///?<returns></returns>
????public?string?CreateVerifyCode()
????{
????????return?CreateVerifyCode(Length,?0);
????}
????
????///?<summary>
????///?生成英文或數字字符
????///?</summary>
????///?<returns></returns>
????protected?char?CreateEnOrNumChar()
????{
????????return?EnglishOrNumChars[rnd.Next(0,?EnglishOrNumChars.Length)];
????}
????///?<summary>
????///?生成漢字字符
????///?</summary>
????///?<returns></returns>
????protected?char?CreateZhChar()
????{
????????//若提供了漢字集,查詢漢字集選取漢字
????????if?(ChineseChars.Length?>?0)
????????{
????????????return?ChineseChars[rnd.Next(0,?ChineseChars.Length)];
????????}
????????//若沒有提供漢字集,則根據《GB2312簡體中文編碼表》編碼規則構造漢字
????????else
????????{
????????????byte[]?bytes?=?new?byte[2];
????????????//第一個字節值在0xb0,?0xf7之間
????????????bytes[0]?=?(byte)rnd.Next(0xb0,?0xf8);
????????????//第二個字節值在0xa1,?0xfe之間
????????????bytes[1]?=?(byte)rnd.Next(0xa1,?0xff);
????????????//根據漢字編碼的字節數組解碼出中文漢字
????????????string?str1?=?Encoding.GetEncoding("gb2312").GetString(bytes);
????????????return?str1[0];
????????}
????}
}
??? 這里面大量使用了51aspx.com的代碼,在此表示感謝。這里的主要改進在于支持生成中英文混合的驗證碼。中文的生成有兩種方式,一是根據《GB2312簡體中文編碼表》編碼規則構造漢字,二是從一個選定的中文字符集合中隨即選取漢字。實現很簡單,參考函數protected?char?CreateZhChar(),在此不贅述。
??? 最后說一下驗證碼的使用,下面是一個例子:??
<img?src="VerifyCode.aspx"?id="valiCode"?alt="驗證碼"?/>
<a?title="刷新驗證碼"?href="#"?onclick="javascript:document.getElementById('valiCode').src='VerifyCode.aspx?id='+Math.random();return?false;">看不清,換張圖片?</a> ??? 這里有個小技巧,就是在刷新驗證碼的使用,驗證碼的URL后面用了隨機參數以欺騙瀏覽器重新請求。
源代碼
2500常用漢字
498常用漢字
轉載于:https://www.cnblogs.com/homer/archive/2007/12/11/VerifyCode.html
新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!總結
以上是生活随笔為你收集整理的[原创]红马版验证码实现(中文+变形+噪点)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaEE实战班第十五天
- 下一篇: 使用WxPython进行Win32下Py