2022年4月14日 星期四

[研究][ASP.NET]WebForm圖形驗證碼(CAPTCHA)程式(二)

[研究][ASP.NET]WebForm圖形驗證碼(CAPTCHA)程式(二)

2022-04-14

環境:Visual Studio 2022 + ASP.NET + WebForm + Web Application + C#

一般常用的 Google reCAPTCHA需要Web Server和Client可以連上Internet,但是若因特殊需求,就不能用 Google reCAPTCHA,需要一個封閉區域網路上可用的。

本篇參考這篇,只是該篇沒有完整可測試範例,本篇進行實際測試。

Simple CAPTCHA, Create Your Own in C# - CodeProject
4 Aug 2010
https://www.codeproject.com/Articles/99148/Simple-CAPTCHA-Create-Your-Own-in-Csharp

Captcha.ashx.cs

using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.IO;
using System.Web;
using System.Web.SessionState;

namespace WebApplication1
{
    /// <summary>
    /// Captcha 的摘要描述
    /// </summary>
    public class Captcha : IHttpHandler, IReadOnlySessionState
    {

        public void ProcessRequest(HttpContext context)
        {
            //context.Response.ContentType = "text/plain";
            //context.Response.Write("Hello World");
            int iHeight = 80;
            int iWidth = 190;
            Random oRandom = new Random();

            int[] aBackgroundNoiseColor = new int[] { 150, 150, 150 };
            int[] aTextColor = new int[] { 0, 0, 0 };
            int[] aFontEmSizes = new int[] { 15, 20, 25, 30, 35 };

            string[] aFontNames = new string[]
            {
                "Comic Sans MS",
                "Arial",
                "Times New Roman",
                "Georgia",
                "Verdana",
                "Geneva"
            };
            FontStyle[] aFontStyles = new FontStyle[]
            {
                FontStyle.Bold,
                FontStyle.Italic,
                FontStyle.Regular,
                FontStyle.Strikeout,
                FontStyle.Underline
            };
            HatchStyle[] aHatchStyles = new HatchStyle[]
            {
                HatchStyle.BackwardDiagonal, HatchStyle.Cross,
                   HatchStyle.DashedDownwardDiagonal, HatchStyle.DashedHorizontal,
                HatchStyle.DashedUpwardDiagonal, HatchStyle.DashedVertical,
                   HatchStyle.DiagonalBrick, HatchStyle.DiagonalCross,
                HatchStyle.Divot, HatchStyle.DottedDiamond, HatchStyle.DottedGrid,
                   HatchStyle.ForwardDiagonal, HatchStyle.Horizontal,
                HatchStyle.HorizontalBrick, HatchStyle.LargeCheckerBoard,
                   HatchStyle.LargeConfetti, HatchStyle.LargeGrid,
                HatchStyle.LightDownwardDiagonal, HatchStyle.LightHorizontal,
                   HatchStyle.LightUpwardDiagonal, HatchStyle.LightVertical,
                HatchStyle.Max, HatchStyle.Min, HatchStyle.NarrowHorizontal,
                   HatchStyle.NarrowVertical, HatchStyle.OutlinedDiamond,
                HatchStyle.Plaid, HatchStyle.Shingle, HatchStyle.SmallCheckerBoard,
                   HatchStyle.SmallConfetti, HatchStyle.SmallGrid,
                HatchStyle.SolidDiamond, HatchStyle.Sphere, HatchStyle.Trellis,
                   HatchStyle.Vertical, HatchStyle.Wave, HatchStyle.Weave,
                HatchStyle.WideDownwardDiagonal, HatchStyle.WideUpwardDiagonal, HatchStyle.ZigZag
            };

            //Get Captcha in Session
            string sCaptchaText = context.Session["Captcha"].ToString();

            //Creates an output Bitmap
            Bitmap oOutputBitmap = new Bitmap(iWidth, iHeight, PixelFormat.Format24bppRgb);
            Graphics oGraphics = Graphics.FromImage(oOutputBitmap);
            oGraphics.TextRenderingHint = TextRenderingHint.AntiAlias;

            //Create a Drawing area
            RectangleF oRectangleF = new RectangleF(0, 0, iWidth, iHeight);
            Brush oBrush = default(Brush);

            //Draw background (Lighter colors RGB 100 to 255)
            oBrush = new HatchBrush(aHatchStyles[oRandom.Next
                (aHatchStyles.Length - 1)], Color.FromArgb((oRandom.Next(100, 255)),
                (oRandom.Next(100, 255)), (oRandom.Next(100, 255))), Color.White);
            oGraphics.FillRectangle(oBrush, oRectangleF);

            System.Drawing.Drawing2D.Matrix oMatrix = new System.Drawing.Drawing2D.Matrix();
            int i = 0;
            for (i = 0; i <= sCaptchaText.Length - 1; i++)
            {
                oMatrix.Reset();
                int iChars = sCaptchaText.Length;
                int x = iWidth / (iChars + 1) * i;
                int y = iHeight / 2;

                //Rotate text Random
                oMatrix.RotateAt(oRandom.Next(-40, 40), new PointF(x, y));
                oGraphics.Transform = oMatrix;

                //Draw the letters with Random Font Type, Size and Color
                oGraphics.DrawString
                (
                //Text
                sCaptchaText.Substring(i, 1),
                //Random Font Name and Style
                new Font(aFontNames[oRandom.Next(aFontNames.Length - 1)],
                   aFontEmSizes[oRandom.Next(aFontEmSizes.Length - 1)],
                   aFontStyles[oRandom.Next(aFontStyles.Length - 1)]),
                //Random Color (Darker colors RGB 0 to 100)
                new SolidBrush(Color.FromArgb(oRandom.Next(0, 100),
                   oRandom.Next(0, 100), oRandom.Next(0, 100))),
                x,
                oRandom.Next(10, 40)
                );
                oGraphics.ResetTransform();
            }

            MemoryStream oMemoryStream = new MemoryStream();
            oOutputBitmap.Save(oMemoryStream, System.Drawing.Imaging.ImageFormat.Png);
            byte[] oBytes = oMemoryStream.GetBuffer();

            oOutputBitmap.Dispose();
            oMemoryStream.Close();

            context.Response.BinaryWrite(oBytes);
            context.Response.End();
        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}


Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" 
    Inherits="WebApplication1.Default" %>

<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <div>
            <asp:TextBox ID="txtCaptcha" runat="server" AutoComplete="Off"></asp:TextBox>
            <br />
            <asp:Image ID="imgCaptcha" ImageUrl="Captcha.ashx" runat="server" />
            <br />
            <asp:Button ID="Button_Check" runat="server" Text="Check" 
                OnClick="Button_Check_Click" />
            <asp:Button ID="Button_Refresh" runat="server" Text="Refresh" 
                OnClick="Button_Refresh_Click" />
            <br />
            <asp:Label ID="Label1" runat="server"></asp:Label>
        </div>
    </form>
</body>
</html>


Default.aspx.cs

using System;

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            Label1.Text = "";
            if (!IsPostBack)
            {
                SetCaptchaText();
            }
        }

        private void SetCaptchaText()
        {
            Random oRandom = new Random();
            //int iNumber = oRandom.Next(100000, 999999);
            int iNumber = oRandom.Next(1000, 9999);
            Session["Captcha"] = iNumber.ToString();
        }

        protected void Button_Check_Click(object sender, EventArgs e)
        {
            if (Session["Captcha"].ToString() != txtCaptcha.Text.Trim())
            {
                //Response.Redirect("Failed.aspx");
                Label1.Text = "Failed";
                SetCaptchaText();
            }
            else
            {
                //Response.Redirect("Success.aspx");
                Label1.Text = "Success";
            }
        }

        protected void Button_Refresh_Click(object sender, EventArgs e)
        {
            SetCaptchaText();
        }
    }
}

執行結果

(完)

相關

[研究][ASP.NET]WebForm圖形驗證碼(CAPTCHA)程式(二)
https://shaurong.blogspot.com/2022/04/aspnetwebformcaptcha_14.html

[研究][ASP.NET]WebForm圖形驗證碼(CAPTCHA)程式(一)
http://shaurong.blogspot.com/2022/04/aspnetwebformcaptcha.html

[研究]ASP.NET WebForm CAPTCHA圖形驗證碼
https://shaurong.blogspot.com/2021/12/aspnet-webform-captcha.html

Simple CAPTCHA, Create Your Own in C# - CodeProject
4 Aug 2010
https://www.codeproject.com/Articles/99148/Simple-CAPTCHA-Create-Your-Own-in-Csharp
(無完整範例,但可用)

A CAPTCHA Server Control for ASP.NET - CodeProject
2007/02/01
https://www.codeproject.com/Articles/8751/A-CAPTCHA-Server-Control-for-ASP-NET
( 程式為 VB + .NET Framework 2.0,要變更專案的屬性為 .NET Framewok 4.8,但執行仍失敗)

A Simple CAPTCHA Image Verification in C# and ASP.Net
2009/02/16
http://www.codedigest.com/CodeDigest/88-A-Simple-CAPTCHA-Image-Verification-in-C--and-ASP-Net.aspx

使用 CAPTCHA 防止 bot 使用您的 ASP.NET Web Razor) 網站
https://docs.microsoft.com/zh-tw/aspnet/web-pages/overview/security/using-a-catpcha-to-prevent-automated-programs-bots-from-using-your-aspnet-web-site


沒有留言:

張貼留言