# 2019/0503/Asp.net泛型處理常式驗證圖片應用&第七次專題報告Usecase

\#40GGetAuthImg.aspx

一般html url要求容易看出伺服器資料夾檔案結構所以需要驗證做安全性管理

而MVC url 要求 token所以就不需要圖形驗證?

{% embed url="<https://www.google.com/search?rlz=1C1GCEU_zh-TWTW835TW836&ei=kI_LXNDQNcaA8wWhv5z4Ag&q=mvc+token+%E6%98%AF%E4%BB%80%E9%BA%BC&oq=mvc+token+%E6%98%AF%E4%BB%80%E9%BA%BC&gs_l=psy-ab.3...1258.4781..5260...0.0..0.128.581.8j1......0....1..gws-wiz.......0j0i30j0i5i30j33i160.927H9pVd6IA>" %}

寫程式方式去畫圖所以CODE會多一點

預防機器人字典攻擊法

不能用文字驗證要用圖片顯示文字不然爬蟲一爬原始檔就知道了

但機器人也可以圖像判斷

所以圖形必須要做干擾讓機器人辨識錯誤但在機器人統計學時代會越來越不適用所以才要用token

### 題外話:&#xD;

AI 在我們這個領域 只講機器學習 而不是人工智慧

機器學習 VS 統計學(應用數學)

老師個人健檢 機器學習可以被訓練

股票前20年股票狀況

24個月4月紅20黑所以5月份跌機率較大

那今年5月份跌或長?

根據統計學來判斷80%&#x20;

但是人工智慧希望做到能夠精準

直接告訴你今天5越漲或跌

會自己學習經過無數次淬鍊(失敗)會自己改進學習???!!!

模型 演算法 學習能力

Deep 深入學習 單一領域很強

逐筆交易每秒合單機器下單

投信?多殺多?賣點賣結果更跌倒置另外一個投信的賣點賣更跌跌

所以當大家都用機器再判斷有個人知道邏輯就能去找弱點

R適合用在商務統計 立即效果

python理工蒐集資料 ( 爬蟲 非結構化資料&#x20;

更早以前是 perl 因為python可以爬網頁

大數據放到哈頓普Hadoop提升效能?&#x20;

{% embed url="<https://www.google.com/search?rlz=1C1GCEU_zh-TWTW835TW836&ei=0ZTLXMjvBtGbmAWhgpT4Bg&q=Hadoop&oq=Hadoop&gs_l=psy-ab.3..0l10.597.12675..13193...0.0..0.219.496.2j1j1......0....1j2..gws-wiz.......0i13i30j0i8i13i30.VpM6uFt-WzI>" %}

老師看好scala

但…

![](/files/-Le0W3rUHwvv1fG4DzXQ)

![](/files/-Le0W6pca3NrRaIuQUj6)

![](/files/-Le0WAfyhxHU2mxVzn8L)

![](/files/-Le0WDqlX4YYfEcZkDRs)

### 回正題&#xD;

泛型處理常式 跟 api 很像

黑盒子 要什麼給什麼 但泛型處理常識沒有介面

但還是要把圖形丟到Interface (不實做??) 來使用

泛型處理常式以前是qrcode產生

現在40GetAuthImg泛型處理常式

![](/files/-Le0WU8mhiiZ2Gz6nZqA)

### 邏輯&#xD;

UX考輛 I大寫哀 l小寫L 大寫歐O數字零0&#x20;

私有函數產生隨機號碼反傳隨機號碼字串

Random物件做操作

以上為何要分為另外一個函數原因為參數化 ( 做成活的

接著要來用這串亂碼參數產生圖片

首先先用一個 Bitmap物件然後用第4種多載(圖的高寬)將亂碼產生bitmap再

去產生graphics圖像物件

{% embed url="<https://www.google.com/search?q=Bitmap&rlz=1C1GCEU_zh-TWTW835TW836&source=lnms&sa=X&ved=0ahUKEwjX3tG-nP7hAhUQGqYKHbPkA5oQ_AUICSgA&biw=1904&bih=927&dpr=1>" %}

這時就畫好圖了這時是黑白的容易被機器人辨識

所以至少做三種漸層並隨機產生rgb

一樣用random物件

然後用color物件去操控顏色數據拿來給graphics物件使用

graphics物件操控清除背景色改為剛剛的亂數顏色數據

接著要用噪音線繼續模糊圖片干擾機器辨識

怎再graphics畫線?

有個方法為drawline

操控物件去drawline有四種多載 我們用第一個

要用silver這支筆

然後給bitmap值的長寬來設置產生噪音線的界線

然後用迴圈畫個80次

接著用矩形物件產生一個矩形

Rectangle給長寬就會畫出一個矩形

所以我們給定bitmap的長寬給他就好

剛剛是整個框內的顏色接著是文字的顏色

將剛剛的亂數取色變數拿來做起始色與結束色用來

System.drawing.drawing2d裡面的lineargradientbrush物件線性筆刷(畫在矩形框內，開頭色，結素色，角度)

接著設定字行(沒設定就是預設的

字型 大小 加粗

接著把字畫進去框框g圖片物件操控

g.drawstring(哪串字，字形，筆刷，位址)

參數都是剛剛上面操控物件之後的變數反傳值

接著要做噪音點setpixel ( 為啥不剛剛噪音線時做?

因為有圖片階層問題 誰先做 誰就在底下

在這做就會蓋住字 但噪音線比字早做所以只會蓋住背景

但方式一樣 只差在只要取 xy即可 不用 x1y1x2y2 因為是點不是線

顏色要用rgb所以fromargb從剛剛上面的亂數 r.next(256)取

然後迴圈幫忙點個500次

用程式畫東西就是這樣沒有介面無法直接看到東西

最後畫外框線

操控g圖片物件用drawrectangle畫

然後用image物件把剛剛的東西都放進去讓他成為一個圖片(檔案可以但不必要

不然會超級多因為只有當下需要用)

操控img物件存成一張圖片的記憶體

圖片位置不一定是檔案也可能是暫存記憶體裡面

利用memory stream 或 file stream 物件去暫時存

Img.save(存在哪，存什麼格式)用第二種多載

最後輸出

清空Context.Response.Clear() barfer緩衝區 ??

指定型態

然後轉成二進置才能用http傳

最後

去前端呼叫泛型處理常式就會返傳圖片

泛型處理常式其實像是介面或是api 會有反傳值過去呼叫的地方

泛型處理常式不用寫建構子用預設的就好

\-----------

還沒講完 現在只是產生圖片 要做驗證對錯 還有 重新產生按鈕

重新產生按鈕只要在前端弄個按鈕重新呼叫泛型處理常式即可

但驗證要利用 session物件 保留生命狀態

再 泛型處理常式內

把剛剛的亂數數字包裹 ( 特殊變數 )

跟區域變數不同

變數生命週期再產生之後到瀏覽器被關掉之前

站內每一個網頁都可以取到session的值

但記得必須要 using sessionstate

繼承irequiressessionstate

![](/files/-Le0Wm-CzkheUYallWaU)

{% embed url="<https://www.google.com/search?rlz=1C1GCEU_zh-TWTW835TW836&tbm=isch&q=session+client&spell=1&sa=X&ved=0ahUKEwimibLHsv7hAhUN7WEKHantBkAQBQg5KAA&biw=1904&bih=927&dpr=1#imgrc=9WcDJTNtTr2KkM>:" %}

接著去後端去將 session轉型成string去比對 textbox2&#x20;

如果是就驗證通過

不是就不通過

不通過不能post 所以要把驗證器改成 Validator

{% embed url="<http://thecodingtime.blogspot.com/2018/01/aspnet-web-formvalidator.html>" %}

#### ###40GetAuthImg.ashx泛型處理常式前端程式碼&#xD;

```
<%@ WebHandler Language="C#" CodeBehind="40GetAuthImg.ashx.cs" Class="ASPnet._40GetAuthImg" %>
```

#### ###40GetAuthImg.ashx.cs泛型處理常式後端程式碼

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Drawing;
using System.IO;
using System.Web.SessionState;

namespace ASPnet
{
    /// <summary>
    /// _40GetAuthImg 的摘要描述
    /// </summary>
    public class _40GetAuthImg : IHttpHandler, IRequiresSessionState
    {

        public void ProcessRequest(HttpContext context)
        {
            int NumCount = 6;
            string strNumber= GetARandomNumber(NumCount);
            context.Session["Number"] = strNumber;

            //產生一個圖片
            Bitmap img = new Bitmap(strNumber.Length * 25, 40);
            //用bitmap產生一個Graphics物件
            Graphics g = Graphics.FromImage(img);

            Random r = new Random();
            int intRed = r.Next(0,256);
            int intGreen = r.Next(0, 256);
            int intBlue = r.Next(0, 256);

            g.Clear(Color.FromArgb(1, intRed, intGreen, intBlue));


            //畫噪音線
            for (int i = 0; i < 60; i++)
            {
                int x1 = r.Next(img.Width);
                int y1 = r.Next(img.Height);
                int x2 = r.Next(img.Width);
                int y2 = r.Next(img.Height);

                g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2);
            }

            //用矩形物件產生一個矩形
            Rectangle MyRect = new Rectangle(0, 0, img.Width, img.Height);
            intRed = r.Next(0, 256);
            intGreen = r.Next(0, 256);
            intBlue = r.Next(0, 256);
            Color color1 = Color.FromArgb(intRed, intGreen, intBlue);

            intRed = r.Next(0, 256);
            intGreen = r.Next(0, 256);
            intBlue = r.Next(0, 256);
            Color color2 = Color.FromArgb(intRed, intGreen, intBlue);

            //文字的顏色(漸層色)
            System.Drawing.Drawing2D.LinearGradientBrush brush = 
                new System.Drawing.Drawing2D.LinearGradientBrush(MyRect,color1,color2, 1.2f);

            //設定字型
            Font font = new Font("Arial Black", 20, FontStyle.Bold);

            //把字畫在矩形框中
            g.DrawString(strNumber, font, brush, 5, 5);

            //噪音點
            for (int i = 0; i < 300; i++)
            {
                int x1 = r.Next(img.Width);
                int y1 = r.Next(img.Height);
              
                img.SetPixel(x1,y1,Color.FromArgb(r.Next(256)));
            }

            //畫外框線
            g.DrawRectangle(new Pen(Color.Silver), 0, 0, img.Width - 1, img.Height - 1);

            //把Bitmap放入Image物件中
            Image image = img;

            //將圖片存成JPG格式置於記憶體中
            MemoryStream ms = new MemoryStream();
            image.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg);

            //output
            context.Response.Clear();
            context.Response.ContentType = "image/jpeg";
            context.Response.BinaryWrite(ms.ToArray());

        }


        private string GetARandomNumber(int n)
        {
            string strNumber = "";
            Random r = new Random();
            for(int i=0;i<n;i++)
            {
                strNumber += r.Next(0,10);
            }

            return strNumber;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

```

#### ###40GGetAuthImg.aspx前端程式碼

```
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="40GGetAuthImg.aspx.cs" Inherits="ASPnet._40GGetAuthImg" %>

<!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:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
            帳號:<asp:TextBox ID="TextBox1" runat="server"></asp:TextBox>
            <br />
            <img src="40GetAuthImg.ashx" />
            <asp:Button ID="Button2" runat="server" Text="重新產生" />

            <br />
            驗證碼:<asp:TextBox ID="TextBox2" runat="server"></asp:TextBox>
 
            <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
            <asp:Label ID="Label1" runat="server" Text=""></asp:Label>
        </div>
       
    </form>
</body>
</html>

```

#### ###40GGetAuthImg.aspx.cs後端程式碼

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace ASPnet
{
    public partial class _40GGetAuthImg : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            if(TextBox2.Text== Session["Number"].ToString())
            {
                Label1.Text = "驗證碼正確";

            }
            else
                Label1.Text = "驗證碼不正確";
        }

     
    }
}

```

#### ###範例圖片

![](/files/-Le0XObOo34ABP3-LpQa)

\#下午第六次專案報告 usecase

感覺沒啥用就不做每組紀錄了

### ##下禮拜報告 組別進度&#xD;


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://johch3n611u.gitbook.io/c50108/ju-li-cheng-bei/201905/20190504asp.net-fan-xing-li-chang-shi-pian-yong-di-wu-ci-an-gao-usecase.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
