随机生成验证码的实现+详细注释

最近的项目里需要使用到随机验证码,所以昨天认真研读了网上的许多教程,但都无非是千篇一律,不太好懂~~~于是乎博主就做了一回好人,对自己已经投入项目使用的一段代码进行详细的解析说明,让大家更好的理解随机验证码的生成原理!!!

这里给上我的验证码类VerifyCode.java

package com.bob.verifycode;

import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

import java.util.Random;

public class VerifyCode {

    private static final char[] CHARS = {//定义随机字符集
            ‘0‘, ‘1‘, ‘2‘, ‘3‘, ‘4‘, ‘5‘, ‘6‘, ‘7‘, ‘8‘, ‘9‘,
            ‘a‘, ‘b‘, ‘c‘, ‘d‘, ‘e‘, ‘f‘, ‘g‘, ‘h‘, ‘i‘, ‘j‘, ‘k‘, ‘l‘, ‘m‘,
            ‘n‘, ‘o‘, ‘p‘, ‘q‘, ‘r‘, ‘s‘, ‘t‘, ‘u‘, ‘v‘, ‘w‘, ‘x‘, ‘y‘, ‘z‘,
            ‘A‘, ‘B‘, ‘C‘, ‘D‘, ‘E‘, ‘F‘, ‘G‘, ‘H‘, ‘I‘, ‘J‘, ‘K‘, ‘L‘, ‘M‘,
            ‘N‘, ‘O‘, ‘P‘, ‘Q‘, ‘R‘, ‘S‘, ‘T‘, ‘U‘, ‘V‘, ‘W‘, ‘X‘, ‘Y‘, ‘Z‘
    };

    private static VerifyCode vCode;

    public static VerifyCode getInstance() {//单例模式获取验证码对象
        if (vCode == null)
            vCode = new VerifyCode();
        return vCode;
    }

//  width="60" height="30"
//          base_padding_left="5"
//          range_padding_left="10"
//          base_padding_top="15"
//          range_padding_top="10"
//          codeLength="4"
//          line_number="3"
//          font_size="20"

    //验证码固定参数,也就是将会用到的几个常量
    private static final int DEFAULT_CODE_LENGTH = 4;//默认的代码长度,也就是会出现4个随机码
    private static final int DEFAULT_FONT_SIZE = 20;//字体大小
    private static final int DEFAULT_LINE_NUMBER = 3;//默认的用于干扰视线直线的条数
    private static final int BASE_PADDING_LEFT = 5, RANGE_PADDING_LEFT = 10, BASE_PADDING_TOP = 15, RANGE_PADDING_TOP = 10;
    /**
     * 上边4个整型数的解释:
     * BASE_PADDING_LEFT,BASE_PADDING_TOP 表示每一个将要画出字符坐标计算的基准
     * RANGE_PADDING_LEFT,RANGE_PADDING_TOP 表示字符坐标x,y的变化范围
     */
    private static final int DEFAULT_WIDTH = 160, DEFAULT_HEIGHT = 30;
    //设置位图宽高,具体的宽高取ImageView和BitMap之间较小的一个,
    // 即就是宽= min{ImageView.Width,Bitmap.Width},高同理
    //注意:当我们需要一个不同尺寸的验证码图片,不仅仅需要修改DEFAULT_WIDTH 和DEFAULT_HEIGHT,为了显示效果
    //的最佳化,最好将上述的4个坐标值也调整一下,使得我们的验证码能最恰当地占据整个底板

    //将一些常量应用到本类的成员变量上
    //settings decided by the layout xml
    //canvas width and height
    private int width = DEFAULT_WIDTH, height = DEFAULT_HEIGHT;

    //random word space and pading_top
    private int base_padding_left = BASE_PADDING_LEFT, range_padding_left = RANGE_PADDING_LEFT,
            base_padding_top = BASE_PADDING_TOP, range_padding_top = RANGE_PADDING_TOP;

    //number of chars, lines; font size
    private int codeLength = DEFAULT_CODE_LENGTH, line_number = DEFAULT_LINE_NUMBER, font_size = DEFAULT_FONT_SIZE;

    //variables
    private String code;//存储随机生成的随机码序列
    private int padding_left, padding_top;//左边框间距和上边框间距
    private Random random = new Random();//随机数生成器

    public Bitmap createBitmap() {//得到位图对象

        padding_left = 0;//设置位图左内边距离

        Bitmap bp = Bitmap.createBitmap(width, height, Config.ARGB_8888);//创建位图
        /**
         * 位图最后一个设置参数的简介
         * A:透明度
         * R:红色
         * G:绿
         * B:蓝
         * Bitmap.Config ARGB_4444:每个像素占四位,即A=4R=4G=4B=4,那么一个像素点占4+4+4+4=16         * Bitmap.Config ARGB_8888:每个像素占四位,即A=8R=8G=8B=8,那么一个像素点占8+8+8+8=32         * Bitmap.Config RGB_565:每个像素占四位,即R=5G=6B=5,没有透明度,那么一个像素点占5+6+5=16         * Bitmap.Config ALPHA_8:每个像素占四位,只有透明度,没有颜色。
         * 一般情况下我们都是使用的ARGB_8888,由此可知它是最占内存的,因为一个像素占32位,8=1字节,所以一个像素占4字节的内存。假设有一张480x800的图片,如果格式为ARGB_8888,那么将会占用1500KB的内存
         */

        Canvas c = new Canvas(bp);//以创建好的空位图创建画布

        code = createCode();//生成目标字符串

        c.drawColor(Color.WHITE);
        Paint paint = new Paint();//创建画笔
        paint.setTextSize(font_size);//设置画笔的字体大小

        for (int i = 0; i < code.length(); i++) {//画每一个字符
            randomTextStyle(paint);//随机的画笔风格
            randomPadding();//按照约定好的规则生成字符的坐标
            c.drawText(code.charAt(i) + "", padding_left, padding_top, paint);//开始以随机的画笔和坐标画每一个字符
        }

        for (int i = 0; i < line_number; i++) {//画事先设置好数量的几条横线
            drawLine(c, paint);
        }

        c.save(Canvas.ALL_SAVE_FLAG);//保存在画布上的所有操作
        c.restore();
        return bp;//返回画好的位图
    }

    public String getCode() {
        return code;
    }

    private String createCode() {//随机生成随机码
        StringBuilder buffer = new StringBuilder();
        for (int i = 0; i < codeLength; i++) {//codeLength即就是验证码字母个数
            buffer.append(CHARS[random.nextInt(CHARS.length)]);
        }
        return buffer.toString();
    }

    private void drawLine(Canvas canvas, Paint paint) {//自定义的任意方向画横线的方法
        int color = randomColor();
        int startX = random.nextInt(width);
        int startY = random.nextInt(height);
        int stopX = random.nextInt(width);
        int stopY = random.nextInt(height);
        paint.setStrokeWidth(1);//设置画笔粗细
        paint.setColor(color);//颜色
        canvas.drawLine(startX, startY, stopX, stopY, paint);
    }

    private int randomColor() {
        return randomColor(1);
    }//随机生成颜色

    private int randomColor(int rate) {
        int red = random.nextInt(256) / rate;
        int green = random.nextInt(256) / rate;
        int blue = random.nextInt(256) / rate;
        return Color.rgb(red, green, blue);
    }

    private void randomTextStyle(Paint paint) {//随机的字体风格
        int color = randomColor();//颜色
        paint.setColor(color);
        paint.setFakeBoldText(random.nextBoolean());  //粗细;true为粗体,false为非粗体
        float skewX = random.nextInt(11) / 10;
        skewX = random.nextBoolean() ? skewX : -skewX;
        paint.setTextSkewX(skewX); //float类型参数,负数表示右斜,整数左斜
//      paint.setUnderlineText(true); //true为下划线,false为非下划线
//      paint.setStrikeThruText(true); //true为删除线,false为非删除线
    }

    /**
     * 随机定义每一个字符所绘画的坐标,注意:在这里padding_left是具有叠加效果的,
     * 也就是说所画的字符越往后,坐标也就越大,而top永远就是base+range
     */
    private void randomPadding() {
        padding_left += base_padding_left + random.nextInt(range_padding_left);
        padding_top = base_padding_top + random.nextInt(range_padding_top);
    }
}

总结一下:随机验证码的生成无非就是通过一个定义好的字符集(可以是52个大小写字母以及10个数字。当然啦既然作为万国码的unicode,博主今后还会视线对汉字的随机生成以及计算公式的验证码)在一张位图上按照事先规定好的随机规则对随机生成的code进行绘画,当然啦,如果对验证码的验证比较复杂,比如公式计算等等,这个code就非常重要了!!!

时间: 2024-10-07 14:42:17

随机生成验证码的实现+详细注释的相关文章

bobojavascript、asp.net 实现随机生成验证码

一些网站中都有登录页面,登录时输入正确的验证码才可以,废话不多说,今天就用javascript 和异步来实现自动生成图片验证码的功能. 首先我们要插入一个一般处理程序(也就是ashx的文件,这里我给它起名为WaterMark.ashx) 这个文件所包括的引用: using System;        using System.Web;        using System.Drawing;        using System.Drawing.Drawing2D;        using

随机生成验证码及python中的事务

1.随机生成验证码 # import random # print(random.random()) #0-1的小数 # print(random.randint(1,3)) #包括1和3 # print("--",random.randrange(1,3)) #不包括1和3 #随机生成四位验证码 import random checkcode = '' for i in range(4): current = random.randrange(0,4) if current != i

Python随机生成验证码的两种方法

Python随机生成验证码的方法有很多,今天给大家列举两种,大家也可以在这个基础上进行改造,设计出适合自己的验证码方法方法一:利用range Python随机生成验证码的方法有很多,今天给大家列举两种,大家也可以在这个基础上进行改造,设计出适合自己的验证码方法 方法一: 利用range方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 # -*- coding: utf-8 -*- import random def generate_verification_c

Android锁定EditText内容和随机生成验证码

昨天写了个小Demo,实现了随机生成验证码,和锁定EditText两个小功能,先看一下效果图: 锁定EditText在我们不需要用户编辑EditText内容的时候可以用到,实现还是很简单的,一行代码: etLock.setEnabled(false); 随机生成验证码,主要是用了Random函数,以及将View转为Bitmap的逻辑,也没有难点,下面贴一下代码,供需要的朋友参考: Main.java package com.zms.textlock; import android.graphic

random 模块,随机生成验证码

随机生成验证码: 此功能利用了chr 和random功能 1 res ='' 2 for i in range(6): 3 num = str(random.randint(0,9)) 4 al_num = random.randint(97,122) 5 al_num2 = random.randint(65,90) 6 alpha = chr(al_num) 7 alpha2 = chr(al_num2) 8 res += random.choice([num,alpha,alpha2])

随机生成验证码

# import random # print(random.random()) #0-1的小数 # print(random.randint(1,3)) #包括1和3 # print("--",random.randrange(1,3)) #不包括1和3 #随机生成四位验证码 import random checkcode = '' for i in range(4): current = random.randrange(0,4) if current != i: temp = c

随机生成验证码信息

package com.dyy.cache; import java.util.HashMap;      import java.util.Map;            /**      * 随机生成中文姓名,性别,Email,手机号,住址      */      public class RandomValue {          public static String base = "abcdefghijklmnopqrstuvwxyz0123456789";      

Django随机生成验证码图片

PIL简介 什么是PIL PIL:是Python Image Library的缩写,图像处理的模块.主要的类包括Image,ImageFont,ImageDraw,ImageFilter PIL的导入 首先需要安装一下pillow包 ? 1 pip install pillow 然后就可以调用PIL里的类了 ? 1 2 3 4 from PIL import Image from PIL import ImageFont from PIL import ImageDraw from PIL im

php随机生成验证码

我们经常需要服务器向前端发送验证码,验证码需要随机产生,下面的用简单的代码实现了这一过程: <?php $pool='0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';//定义一个验证码池,验证码由其中几个字符组成 $word_length=6;//验证码长度 $code = '';//验证码 for ($i = 0, $mt_rand_max = strlen($pool) - 1; $i < $word_leng