黑马程序员技术交流社区

标题: C#写验证码问题 [打印本页]

作者: 董志    时间: 2011-12-13 18:38
标题: C#写验证码问题
本帖最后由 董志 于 2011-12-20 12:54 编辑

下面这段程序是用C#写验证码,单步调试结果正常,但是运行起来总是一串相同字符,望高手指点
(主界面一按钮,一个pictureBox)
  1.         private void button1_Click(object sender, EventArgs e)
  2.         {
  3.             Bitmap bmp = new Bitmap(200, 40);
  4.             string code = null;
  5.             List<string> chars = new List<string>();
  6.             for (int i = 0; i < 10; i++) {
  7.                 chars.Add(i.ToString());
  8.             }
  9.             for (int i = 65; i < 90; i++) {
  10.                 chars.Add(Convert.ToChar(i).ToString());
  11.             }
  12.             for (int i = 0; i < 5; i++) {
  13.                 int n = new Random().Next(0, chars.Count);
  14.                 code += chars[n];
  15.             }
  16.             Graphics g = Graphics.FromImage(bmp);
  17.             Color c1 = Color.FromArgb(new Random().Next(0, 150), new Random().Next(0, 150), new Random().Next(0, 150));
  18.             Color c2 = Color.FromArgb(new Random().Next(0, 150), new Random().Next(0, 150), new Random().Next(0, 150));
  19.             Brush b = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(0,0),new Point(100,100),c1,c2);
  20.             g.DrawString(code, new Font("Arial", 20.0F), b, new Point(5,5));
  21.             pictureBox1.Image = bmp;
  22.             bmp.Save("code.jpg");
  23.         }
复制代码

作者: 乔克    时间: 2011-12-13 19:33
  1.         private void button1_Click(object sender, EventArgs e)
  2.         {
  3.             Bitmap bmp = new Bitmap(200, 40);
  4.             string code = null;
  5.             List<string> chars = new List<string>();
  6.             for (int i = 0; i < 10; i++)
  7.             {
  8.                 chars.Add(i.ToString());
  9.             }
  10.             for (int i = 65; i < 90; i++)
  11.             {
  12.                 chars.Add(Convert.ToChar(i).ToString());
  13.             }
  14.             int n;
  15.             int[] charIndexs = new int[5];
  16.             int myIndex = 0;
  17.             Random r = new Random();
  18.             //生成五个不同的随机数。
  19.             while (true)
  20.             {

  21.                 int x = r.Next(0, chars.Count());
  22.                
  23.                 if (charIndexs.Contains(x))    //如果已有该随机数,则继续下次循环
  24.                     continue;
  25.                 else
  26.                 {
  27.                     charIndexs[myIndex] = x; //如果没有该随机数,则保存到字典d中
  28.                     myIndex++;
  29.                 }

  30.                 if (myIndex >= 5)    //5是你要的N个随机数,你可以把N改成你想要的随机数个数
  31.                     break;

  32.             }
  33.             for (int i = 0; i < 5; i++)
  34.             {
  35.                
  36.                 //n = r.Next(0, chars.Count());
  37.                 //n = new Random().Next(0, chars.Count);
  38.                 code += chars[charIndexs[i]];
  39.             }
  40.             Graphics g = Graphics.FromImage(bmp);
  41.             Color c1 = Color.FromArgb(new Random().Next(0, 150), new Random().Next(0, 150), new Random().Next(0, 150));
  42.             Color c2 = Color.FromArgb(new Random().Next(0, 150), new Random().Next(0, 150), new Random().Next(0, 150));
  43.             Brush b = new System.Drawing.Drawing2D.LinearGradientBrush(new Point(0, 0), new Point(100, 100), c1, c2);
  44.             g.DrawString(code, new Font("Arial", 20.0F), b, new Point(5, 5));
  45.             pictureBox1.Image = bmp;
  46.             bmp.Save("code.jpg");
  47.         }
复制代码

作者: 余飞    时间: 2011-12-13 19:39
  问题出在随机数获取上,改成下面的就OK了


            Random random = new Random();
            for (int i = 0; i < 5; i++)
            {
                int n =random.Next(0, chars.Count);
                code += chars[n];
            }


作者: 董志    时间: 2011-12-14 10:47
random 初始化在循环外面和在循环里面有什么深层次区别吗?
作者: liuyinggzu    时间: 2011-12-14 11:42
本帖最后由 liuyinggzu 于 2011-12-14 11:43 编辑

Random类是一个产生伪随机数字的类,它的构造函数有两种,一个是直接New Random(),另外一个是New Random(Int32),前者是根据触发那刻的系统时间做为种子,来产生一个随机数字,后者可以自己设定触发的种子,一般都是用UnCheck((Int)DateTime.Now.Ticks)做为参数种子,因此如果计算机运行速度很快,如果触发Random函数间隔时间很短,就有可能造成产生一样的随机数,因为伪随机的数字,在Random的内部产生机制中还是有一定规律的,并非是真正意义上的完全随机。
作者: 董志    时间: 2011-12-20 12:52
单步调试时,系统时间不一样了,所以产生了不一样的随i机数,运行时太快了,所以就会造成随机数相同。呵呵




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2