简单的验证码图片生成

时间:2023-02-04 22:46:48

1 验证码介绍

验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。

它可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上用验证码是现在很多网站通行的方式,我们利用比较简易的方式实现了这个功能。这个问题可以由计算机生成并评判,但是必须只有人类才能解答。由于计算机无法解答CAPTCHA的问题,所以回答出问题的用户就可以被认为是人类。

2.2 Random 函数( Java.util.Random() )

实验中使用了生成随机数的函数 Random 。首先简单了解一下这个函数的方法。

  • boolean nextBoolean():返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的boolean值。
  • double nextDouble():返回下一个伪随机数,它是取自此随机数生成器序列的、在0.0和1.0之间均匀分布的 double值。
  • float nextFloat():返回下一个伪随机数,它是取自此随机数生成器序列的、在0.0和1.0之间均匀分布float值。
  • double nextGaussian():返回下一个伪随机数,它是取自此随机数生成器序列的、呈高斯(“正态”)分布的double值,其平均值是0.0标准差是1.0。
  • int nextInt():返回下一个伪随机数,它是此随机数生成器的序列中均匀分布的 int 值。
  • int nextInt(int n):返回一个伪随机数,该方法的作用是生成一个随机的int值,该值介于[0,n)的区间,也就是0到n之间的随机int值,包含0而不包含n。
  • long nextLong():返回下一个伪随机数,它是取自此随机数生成器序列的均匀分布的 long 值。

2.3 StringBuffer

String 和 StringBuffer 他们都可以存储和操作字符串,即包含多个字符的字符串数据。

String 类是字符串常量,是不可更改的常量。而 StringBuffer 是字符串变量,它的对象是可以扩充和修改的。

StringBuffer 类的构造函数 public StringBuffer() 创建一个空的 StringBuffer 类的对象。public StringBuffer( int length ) 创建一个长度为参数 length 的 StringBuffer 类的对象。

注意:如果参数 length 小于 0 ,将触发 NegativeArraySizeException 异常。 public StringBuffer( String str ) 用一个已存在的字符串常量来创建 StringBuffer 类的对象。

StringBuffer 的函数主要有:

  • StringBuffer append(boolean b): 向字符串缓冲区“追加”元素,但是,这个“元素”参数可以是布尔量、字符、字符数组、双精度数、浮点数、整型数、长整型数对象类型的字符串、字符串和 StringBuffer 类等。如果添加的字符超出了字符串缓冲区的长度,Java 将自动进行扩充。
  • char charAt(int index) :在当前StringBuffer对象中取索引号为index的字符。第一个字符的索引为“0”。
  • StringBuffer delete(int start, int end): 删除当前StringBuffer对象中以索引号 start 开始,到 end 结束的子串。
  • void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin): 从当前 StringBuffer 对象的索引号 srcBegin 开始,到 srcEnd 结束的子串,赋值到字符数组 dst 中,并且从 dst 的索引号 dstBegin 开始。
  • int indexOf(String str): 返回当前 StringBuffer 对象中,第一个满足 str 子串的位置。
  • int length(): 返回当前StringBuffer对象(字符缓冲区)中,字符串的长度。注意:此方法与 capacity() 不同。

2.4 OutputStream 字节流输出

OutputStream 是所有表示位输出流的类之父类,它是一个抽象类。

子类要重新定义其中所定义的抽象方法,OutputStream是用于将数据写入目的地的抽象表示。例如 System 中的标准输出流对象out其类型是 java.io.PrintStream ,这个类是 OutputStream 的子类 (java.io.FilterOutputStream 继承 OutputStream, PrintStream 再继承 FilterOutputStream )。

在程序开始之后,out 流对象就会开启,可以通过 out 来将数据写至目的地装置,这个装置通常是屏幕显示或用户定义的输出装置。

本次我们用到的方法有:

  • write(int) 写一个字节到流中
  • write(byte[]) 将数组中的内容写到流中
  • write(byte[],int off,int len) 将数组中从off指定的位置开始len长度的数据写到流中
  • close() 关闭流
  • flush() 将缓冲区中的数据强制输出

2.5 Servlet 简介

Servlet(Server Applet),全称 Java Servlet 。它是用 Java 编写的服务器端程序。其主要功能在于交互式地浏览和修改数据,生成动态 Web 内容。狭义的 Servlet 是指 Java 语言实现的一个接口,广义的 Servlet 是指任何实现了这个 Servlet 接口的类,一般情况下,人们将 Servlet 理解为后者。 Servlet 运行于支持 Java 的应用服务器中。从原理上讲,Servlet 可以响应任何类型的请求,但绝大多数情况下 Servlet 只用来扩展基于 HTTP 协议的 Web 服务器。

2.5.1 主要编程接口

HTTPServlet 使用一个 HTML 表单来发送和接收数据。

要创建一个 HTTPServlet,请扩展 HttpServlet 类, 该类是用专门的方法来处理 HTML 表单的 GenericServlet 的一个子类。

HTML 表单是由 <form></form> 标记定义的.表单中典型地包含输入字段(如文本输入字段、复选框、单选按钮和选择列表)和用于提交数据的按钮。

当提交信息时,它们还指定服务器应执行哪一个Servlet(或其它的程序)。 HttpServlet 类包含 init()destroy()service() 等方法。其中init()destroy() 方法是继承的。

1. init() 方法

在 Servlet 的生命期中,仅执行一次 init() 方法。它是在服务器装入 Servlet 时执行的。可以配置服务器,以在启动服务器或客户机首次访问 Servlet 时装入 Servlet。 无论有多少客户机访问 Servlet,都不会重复执行 init() 。

缺省的 init() 方法通常是符合要求的,但也可以用定制 init() 方法来覆盖它,典型的是管理服务器端资源。 例如,可能编写一个定制 init() 来只用于一次装入 GIF 图像,改进 Servlet 返回 GIF 图像和含有多个客户机请求的性能。

另一个示例是初始化数据库连接。缺省的 init() 方法设置了 Servlet 的初始化参数,并用它的 ServletConfig 对象参数来启动配置, 因此所有覆盖 init() 方法的 Servlet 应调用 super.init() 以确保仍然执行这些任务。

在调用 service() 方法之前,应确保已完成了 init() 方法。

2. doGet() 方法

当一个客户通过 HTML 表单发出一个 HTTP GET 请求或直接请求一个 URL 时,doGet() 方法被调用。与 GET 请求相关的参数添加到 URL 的后面,并与这个请求一起发送。当不会修改服务器端的数据时,应该使用 doGet() 方法。

3. doPost() 方法 当一个客户通过 HTML 表单发出一个 HTTP POST 请求时,doPost() 方法被调用。与 POST 请求相关的参数作为一个单独的 HTTP 请求从浏览器发送到服务器。当需要修改服务器端的数据时,应该使用 doPost() 方法。


未完待续


以及

Java实现简单的支付平台业务流程