用C#實現簡單的帶有驗證碼及密碼使用MD5加密的“登入”WinForm小程式
阿新 • • 發佈:2019-02-14
初學C#Windows窗體程式時,做個簡單的“登入”是再簡單不過的了。像下面這樣的,功能稍理想了吧?
有後臺數據庫,有驗證碼,資料庫中密碼是密文(如圖所示:資料庫中表資料是32位MD5加密的……) 下面講解如何實現。 步驟: 1、建立相應的資料庫,建立表,設定欄位及其屬性,設計觸發器 2、建立WinForm窗體程式 3、設計窗體 4、編輯程式碼 程式流程: 1、使用者輸入賬號、密碼,驗證碼 2、提交 3、連線資料庫、查詢密碼 4、成功匹配對應賬號密碼則跳轉到指定窗體,失敗則返回登陸窗體 要點: 1、前臺介面如何設計? ANS:使用label、textbox、button控制元件 2、後臺資料庫中密碼欄位如何加密為密文? ANS:使用簡單的MD5加密演算法 3、前臺textbox中的資料如何和後臺資料庫中的密文匹配? ANS:將前臺textbox中的資料同樣加密,與後臺密文匹配。(加密演算法具有唯一性、單向性)
環境:
- 機器:windows 7 64 bit
- IDE:Visual Studio 2012 Ultimate
- 資料庫:SQL Server 2005
1、資料庫部分
資料庫使用兩張表,分別儲存使用者登入資訊及使用者註冊資訊。 1.1 表idpassword |number|id|password| |------|--|--------| 1.2 表registerinformation | number| id | password | name | mail | |-------|----|----------|------|------| 1、3 觸發器 trg_EncryptPwd
--sql觸發器,自動加密前臺傳入的密碼欄位
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER TRIGGER [trg_EncryptPwd]
ON [dbo].[idpassword]
AFTER INSERT,UPDATE
AS
BEGIN
IF(UPDATE(password))
BEGIN
DECLARE @uid varchar(32)
DECLARE @pwd varchar(32)
-- 獲取使用者ID和密碼
SELECT @uid=id,@pwd=password FROM inserted
-- 更新密碼
UPDATE idpassword SET password = dbo.MD5(@pwd,32) WHERE id = @uid
END
END
-- 註冊使用者時,自動將使用者密碼加密。
2、前臺檢視
使用label、textbox、button控制元件。
3、程式碼
程式碼部分包含6位驗證碼(區分大小寫)的生成、WinForm窗體的跳轉、前臺textbox中密碼的加密、前臺輸入的賬號與後臺資料庫中的資料的匹配……
登入窗體程式碼:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Data.Sql;
using System.Security.Cryptography;
/* 程式內容:實現簡單登陸程式,使用賬號,密碼登入。
* 窗體:
* Login.cs :
* 控制元件: label1 賬號: label2 密碼:
* texId 賬號 texPwd 密碼
* button1 登陸 button2 註冊
*
* Register.cs
* 控制元件: label1 賬號: label2 密碼:label3 姓名: label4 郵箱:
* texId 賬號 texPwd 密碼 texName 姓名 texMail 郵箱
* button1 註冊 button2 重置
*
* 作者:zhoujl
* -------------------------2017年10月25日09:03:38----------------------
*
*/
namespace LoginDateBase
{
public partial class Login : Form
{
//隨機碼的長度
private const int iVerifyCodeLength = 6;
//隨機碼
private String strVerifyCode = "";
public Login()
{
InitializeComponent();
UpdateVerifyCode();
}
/// <summary>
/// 更新驗證碼
/// </summary>
private void UpdateVerifyCode()
{
strVerifyCode = CreateRandomCode(iVerifyCodeLength);
CreateImage(strVerifyCode);
}
/// <summary>
/// 建立隨機碼圖片
/// </summary>
/// <param name="strVerifyCode"></param>
private void CreateImage(string strVerifyCode)
{
try
{
int iRandAngle = 45; //隨機轉動角度
int iMapWidth = (int)(strVerifyCode.Length * 21);
Bitmap map = new Bitmap(iMapWidth, 28); //建立圖片背景
Graphics graph = Graphics.FromImage(map);
graph.Clear(Color.AliceBlue);//清除畫面,填充背景
graph.DrawRectangle(new Pen(Color.Black, 0), 0, 0, map.Width - 1, map.Height - 1);//畫一個邊框
graph.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;//模式
Random rand = new Random();
//背景噪點生成
Pen blackPen = new Pen(Color.LightGray, 0);
for (int i = 0; i < 50; i++)
{
int x = rand.Next(0, map.Width);
int y = rand.Next(0, map.Height);
graph.DrawRectangle(blackPen, x, y, 1, 1);
}
//驗證碼旋轉,防止機器識別
char[] chars = strVerifyCode.ToCharArray();//拆散字串成單字元陣列
//文字距中
StringFormat format = new StringFormat(StringFormatFlags.NoClip);
format.Alignment = StringAlignment.Center;
format.LineAlignment = StringAlignment.Center;
//定義顏色
Color[] c = { Color.Black, Color.Red, Color.DarkBlue, Color.Green, Color.Orange, Color.Brown, Color.DarkCyan, Color.Purple };
//定義字型
string[] font = { "Verdana", "Microsoft Sans Serif", "Comic Sans MS", "Arial", "宋體" };
for (int i = 0; i < chars.Length; i++)
{
int cindex = rand.Next(7);
int findex = rand.Next(5);
Font f = new System.Drawing.Font(font[findex], 13, System.Drawing.FontStyle.Bold);//字型樣式(引數2為字型大小)
Brush b = new System.Drawing.SolidBrush(c[cindex]);
Point dot = new Point(16, 16);
float angle = rand.Next(-iRandAngle, iRandAngle);//轉動的度數
graph.TranslateTransform(dot.X, dot.Y);//移動游標到指定位置
graph.RotateTransform(angle);
graph.DrawString(chars[i].ToString(), f, b, 1, 1, format);
graph.RotateTransform(-angle);//轉回去
graph.TranslateTransform(2, -dot.Y);//移動游標到指定位置
}
pictureBox1.Image = map;
}
catch (ArgumentException)
{
MessageBox.Show("建立圖片錯誤。");
}
}
/// <summary>
/// 建立驗證碼
/// </summary>
/// <param name="iLength"></param>
/// <returns></returns>
private string CreateRandomCode(int iLength)
{
int rand;
char code;
string randomCode = String.Empty;
//生成一定長度的驗證碼
System.Random random = new Random();
for (int i = 0; i < iLength; i++)
{
rand = random.Next();
if (rand % 3 == 0)
{
code = (char)('A' + (char)(rand % 26));
}
else
{
code = (char)('0' + (char)(rand % 10));
}
randomCode += code.ToString();
}
return randomCode;
}
private void Login_Load(object sender, EventArgs e)
{
this.ActiveControl = this.txtId;
}
private void Login_Paint(object sender, PaintEventArgs e)
{
}
/// <summary>
/// 登陸
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
//連線資料庫為SQL Server 2005
//定義連結字串
string connString = "server=.;user id=sa;password=sa;database=register";
//1.建立連線物件
SqlConnection conn = null;
try
{
conn = new SqlConnection(connString);
}
catch (Exception e1)
{
e1.ToString();
MessageBox.Show("建立連線物件出錯");
}
//md5 32位加密
byte[] result = Encoding.Default.GetBytes(this.txtPwd.Text.Trim()); //輸入密碼的文字框
MD5 md5 = new MD5CryptoServiceProvider();
byte[] output = md5.ComputeHash(result);//加密後的登陸明文密碼
this.txtPwd.Text = BitConverter.ToString(output).Replace("-", ""); //為輸出加密文字的文字框
string sqlLog = "select * from idpassword where id='"
+ txtId.Text.Trim() + "'and password='" + this.txtPwd.Text + "' ";
try
{
//2.開啟連線
conn.Open();
}
catch (Exception e2)
{
e2.ToString();
MessageBox.Show("資料庫連接出錯");
}
if (txtId.Text.Equals("") || txtPwd.Text.Equals(""))//賬號,密碼為空
{
MessageBox.Show("請輸入賬號密碼");
}
else if (textBox1.Text.Equals("") || !textBox1.Text.Equals(strVerifyCode))//驗證碼為空或錯誤
{
MessageBox.Show("驗證碼錯誤");
}
else
{
//資料庫tra-sql語句
//3.執行查詢
SqlCommand cmdL = new SqlCommand(sqlLog, conn);
//從資料庫讀一行
SqlDataReader sread = cmdL.ExecuteReader();
int count = 0;
while (sread.Read())
{
count++;
}
//4.關閉連線
conn.Close();
if (count > 0)
{
MessageBox.Show("登陸成功");
//登陸成功則跳轉至新的窗體
Search search = new Search();
//查詢視窗
search.Show();
}
else
{
MessageBox.Show("登入失敗");
}
}
}
private void button2_Click(object sender, EventArgs e)//註冊
{
Register form2 = new Register();
form2.Show();
}
/// <summary>
/// 重新整理驗證碼
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click(object sender, EventArgs e)//更換驗證碼
{
UpdateVerifyCode();
}
}
}
註冊窗體程式碼
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
using System.Data.Sql;
namespace LoginDateBase
{
public partial class Register : Form
{
public Register()
{
InitializeComponent();
}
//清空輸入
public void c()
{
txtIdR.Text = "";
txtPwdR.Text = "";
txtName.Text = "";
txtMail.Text = "";
}
private void Registe_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
//輸入不能為空
if (txtIdR.Text == "" | txtPwdR.Text == "" | txtName.Text == "" | txtMail.Text == "")
{
MessageBox.Show("請輸入完整資訊");
return;
}
///LoginId不能為重複
//定義連結字串
string connString = "server=.;user id=sa;password=sa;database=register";
//1.建立連線物件
SqlConnection conn = new SqlConnection(connString);
//組合sql查詢語句
string sqlSelect = "select id from registerinformation where id='" + txtIdR.Text.Trim() + "'";
SqlCommand cmd1 = new SqlCommand(sqlSelect, conn);
//2.開啟連線
//3.執行查詢
conn.Open();
object result1 = cmd1.ExecuteScalar();
//判斷賬號是否重複
if (result1 != null)
{
MessageBox.Show("該賬戶已被註冊");
conn.Close();
return;
}
//4.關閉連線
conn.Close();
//添加註冊資訊SQL語句
string sql = "insert into registerinformation(id,password,name,mail)";
sql += "values('{0}','{1}','{2}','{3}')";
sql = string.Format(sql, txtIdR.Text, txtPwdR.Text, txtName.Text, txtMail.Text);
SqlCommand cmd = new SqlCommand(sql, conn);
//開啟連線
conn.Open();
//執行操作
int reslt = cmd.ExecuteNonQuery();
conn.Close();
//清空輸入
c();
//註冊成功
MessageBox.Show("註冊成功");
this.Close();
}
private void button2_Click(object sender, EventArgs e)
{
c();
txtIdR.Focus();
}
}
}
後記:
時間倉促,本人水平也有限,若各位讀者發現錯誤歡迎批評指正!