用C#实现简单的带有验证码及密码使用MD5加密的“登录”WinForm小程序

初学C#Windows窗体程序时,做个简单的“登录”是再简单不过的了。像下面这样的,功能稍理想了吧?

2019年9月21日 18:28:19


这里写图片描述
这里写图片描述
数据库登陆表

有后台数据库,有验证码,数据库中密码是密文(如图所示:数据库中表数据是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]
//这里注意,初次建立触发器,请将ALTER修改为CREATE

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();
        }
    }
}

后记:
       时间仓促,本人水平也有限,若各位读者发现错误欢迎批评指正!
  • 13
    点赞
  • 97
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 18
    评论
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jerryzhou;

您的鼓励,将是我的动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值