-
1 # 科技小夥子丶
-
2 # 小小猿愛嘻嘻
這個實現起來不難,Java生成隨機驗證碼,最主要的是繪製字元及干擾線,下面我簡單介紹一下實現過程,感興趣的朋友可以嘗試一下:
01設定驗證碼樣式首先,設定需要生成驗證碼的樣式,這個是繪製驗證碼的基礎和必須條件,包括字型、可選字符集、背景色、影象寬度、影象高度、字元個數等,後面繪製函式就是根據這些設定的屬性繪製驗證碼,可以設計的複雜,也可以設計的簡單,這裡我只做了簡單必須要的設定:
02繪製驗證碼樣式設定完成後,我們就可以直接繪製驗證碼了,測試程式碼如下,基本思想先建立一個圖片緩衝區(即BufferedImage物件),然後得到繪製環境(即Graphics2D物件),最後再直接根據屬性繪製驗證碼並儲存即可,包括背景色、字型、旋轉角度的設計以及干擾線的繪製等,程式碼量比較多,但理解起來並不難:
03生成驗證碼繪製函式編寫完成後,就是在main函式中呼叫生成驗證碼,這裡就非常簡單了,建立一個VerifyCode類物件,然後直接呼叫drawImage函式即可,程式成功執行後,會在指定目錄下生成一個驗證碼圖片:
至此,我們就完成了利用Java生成隨機驗證碼。總的來說,整個過程非常簡單,最主要的是字元和干擾線的繪製,只要你有一定Java基礎,熟悉一下上面的程式碼和示例,很快就能掌握的,網上也有相關教程和資料,介紹的非常詳細,感興趣的話,可以搜一下,希望以上分享的內容能對你有所幫助吧,也歡迎大家評論、留言進行補充。
-
3 # IT資訊i
【北京】IT技術人員面對面試、跳槽、升職等問題,如何快速成長,獲得大廠入門資格和升職加薪的籌碼?與大廠技術大牛面對面交流,解答你的疑惑。《從職場小白到技術總監成長之路:我的職場焦慮與救贖》活動連結:http://mk1.top/1ndjnvb
最後邊給出了完整的程式碼。
//首先定義一個自己的類並且去繼承HttpServlet這個類
public class CheckImg extends HttpServlet{
//複寫HttpServlet中的doGet方法
public void doGet(HttpServletRequest req,HttpServletResponse resp) throws ServletException,
IOException{
//準備一張畫紙,將驗證碼中的數字字母寫到這張畫紙中
int width = 120;
int height = 30;
BufferedImage bufi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//這裡面的width、height、就是這張畫紙的長寬。BufferedImage.TYPE_INT_RGB就是這張畫紙基於
//RGB三原色來進行畫
//這個時候並沒有在這張紙上書寫任何內容,但是已經可以像客戶端響應請求了
ImageIO.write(bufi, "jpg", resp.getOutputStream());
}
}
這時候可以在瀏覽器上看到一個長120,高30的矩形小框。
//設定畫筆顏色
g.setColor(Color.WHITE);
//將這個顏色填充到整個畫紙
g.fillRect(0,0,width,height);
瀏覽器上就顯示出來一個白色的小框也就是上邊定義的畫紙
開始在畫紙上畫驗證碼了。
//定義圖片上可以寫什麼資料
String data = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890";
//定義書寫在畫紙上的起始位置
int x =15;
int y =25;
//定義一個隨機數
Random r = new Random();
//定義一個StringBuilder字串緩衝區
StringBuilder sb = new StringBuilder();
//定義一個迴圈給畫紙上寫四個資料
for(int i = 0; i < 4; i++){
//從data中隨機獲取一個下標的資料
char c = data.charAt(r.nextInt(data.length()));
//每寫一個數據就將這個數放到字串緩衝區中
sb.append(c+"")
//隨機生成畫筆的顏色,RGB三原色隨機在0-256中隨機生成
g.setColor(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));
//設定字型
g.setFont(new Font("黑體",Font.BOLD,26));
//將資料寫到畫紙上
g.drawString(c+"",x,y);
//沒寫完一個調整下一個資料寫的位置
x += 25;
}
//迴圈結束也就是所有的資料都放在字串緩衝區中
HttpSession session = req.getSession();
session.setAttribute("checkNum",sb.toString());
再重啟tomcat在瀏覽器上能看到書寫驗證碼了
在畫紙上新增干擾資訊
//新增線型別的干擾資訊for(int i = 0; i < 15 ; i++){
//同樣設定線的顏色
g.setColor(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));
//開始劃線,這裡需要的四個引數中前兩個是線開頭的左邊,後邊兩個是線結束的座標
g.drawLine(r.nextInt(width),r.nextInt(height),r.nextInt(width),r.nextInt(height));
}
//新增點型別干擾資訊
for (int i = 0 ; i < 150 ; i++){
//設定點的顏色
g.setColor(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));
//開始畫點,實質上這是畫橢圓,將上半軸半徑,左半軸半徑設定為0就可以看成是一個點
g.drawOval(r.nextInt(width),r.nextInt(height),0,0);
}
在瀏覽器上就能看到驗證碼上充滿點和橫線,降低辨識度
貌似還沒有達到想要的結果,將字型設定一點傾斜度就更好了
//設定資料旋轉
double theta =(30 - (r.nextInt(60)))*Math.PI/180;
g.rotate(theta,x,24);
//將資料寫到畫紙上
g.drawString(c+"",x,y);
//設定完旋轉要調回,防止資料旋轉的看不到
g.rotate(-theta,x,24);
可以看到圖片中的資料進行了略微的傾斜
html註冊頁面程式碼這裡只截取了body和script部分的程式碼
<body>
<fieldset>
<legend>註冊頁面</legend>
<form action="/day02/register2" method="post" >
<table>
<tr>
<td>使用者名稱:</td>
<td><input type="text" name="userName" /><span></span></td>
</tr>
<tr>
<td>
密碼:
</td>
<td>
<input type="password" name="password" />
</td>
</tr>
<tr>
<td>
確認密碼:
</td>
<td>
<input type="password" name="repassword" />
<span></span>
</td>
</tr>
<tr>
<td>
性別:
</td>
<td>
<input type="radio" name="sex" value="男" />男
<input type="radio" name="sex" value="女" />女
<span></span>
</td>
</tr>
<tr>
<td>愛好:</td>
<td>
<input type="checkbox" name="hobby" value="唱" />唱
<input type="checkbox" name="hobby" value="跳" />跳
<input type="checkbox" name="hobby" value="rap" />rap
<input type="checkbox" name="hobby" value="籃球" />籃球
<span></span>
</td>
</tr>
<tr>
<td>國籍:</td>
<td>
<select name="country">
<option value="none">--請選擇國籍--</option>
<option value="中國">中國</option>
<option value="南韓">南韓</option>
<option value="日本">日本</option>
<option value="美國">美國</option>
</select>
<span></span>
</td>
</tr>
<tr>
<td>自我評價:</td>
<td>
<textarea rows="10px" cols="20px" name="describe" ></textarea>
</td>
</tr>
<tr>
<td>
驗證碼:
</td>
<td>
//定義一個input標籤,使用者輸入驗證碼
<input type="text" name="check"/>
//input標籤後連結了上邊寫的驗證碼生成Servlet程式
<img src="/day02/demo" onclick="checkImg()" style = "cursor: pointer">
</td>
</tr>
</table>
<input type="submit" value="提交" />
<input type="button" value="驗證" />
</form>
</fieldset>
</body>
<script type="text/javascript">
function checkImg() {
//透過ID屬性拿到img標籤
var img = document.getElementById("img");
//當瀏覽器發現兩次請求的URL相同時不會主動的向伺服器請求圖片
//所以需要實時的更改URL,這裡採用的是在URL後邊拼接一個當前系統時間的毫秒值
//這樣就能保證每一毫秒的URL都不同,從而瀏覽器會給伺服器傳送圖片的請求
img.src ="/day02/demo?"+new Date().getTime()
}
</script>
完整的程式碼
@WebServlet(urlPatterns = "/demo")
public class CheckImg extends HttpServlet {
//複寫HttpServlet中的doGet方法
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException,
IOException{
//準備一張畫紙,將驗證碼中的數字字母寫到這張畫紙中
int width = 120;
int height = 30;
BufferedImage bufi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
//這裡面的width、height、就是這張畫紙的長寬。BufferedImage.TYPE_INT_RGB就是這張畫紙基於
//RGB三原色來進行畫
//獲取一個畫筆物件,給圖片上畫畫
Graphics2D g = (Graphics2D) bufi.getGraphics();
//設定畫筆顏色
g.setColor(Color.WHITE);
//將這個顏色填充到整個畫紙
g.fillRect(0,0,width,height);
//定義圖片上可以寫什麼資料
String data = "QWERTYUIOPASDFGHJKLZXCVBNMqwertyuiopasdfghjklzxcvbnm1234567890";
//定義書寫在畫紙上的起始位置
int x =15;
int y =25;
//定義一個隨機數
Random r = new Random();
//定義一個迴圈給畫紙上寫四個資料
for(int i = 0; i < 4; i++){
//從data中隨機獲取一個下標的資料
char c = data.charAt(r.nextInt(data.length()));
//隨機生成畫筆的顏色,RGB三原色隨機在0-256中隨機生成
g.setColor(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));
//設定字型
g.setFont(new Font("黑體",Font.BOLD,26));
//設定資料旋轉
double theta =(30 - (r.nextInt(60)))*Math.PI/180;
g.rotate(theta,x,24);
//將資料寫到畫紙上
g.drawString(c+"",x,y);
//設定完旋轉要調回,防止資料旋轉的看不到
g.rotate(-theta,x,24);
//將資料寫到畫紙上
g.drawString(c+"",x,y);
//g.rotate(-theta,r.nextInt(width),24);
//設定完旋轉要調回,防止資料旋轉的看不到
g.rotate(-((10)*3.14/180),15*i+8,7);
//每寫完一個調整下一個資料寫的位置
x += 25;
}
//新增線型別的干擾資訊
for(int i = 0; i < 15 ; i++){
//同樣設定線的顏色
g.setColor(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));
//開始劃線,這裡需要的四個引數中前兩個是線開頭的左邊,後邊兩個是線結束的座標
g.drawLine(r.nextInt(width),r.nextInt(height),r.nextInt(width),r.nextInt(height));
}
//新增點型別干擾資訊
for (int i = 0 ; i < 150 ; i++){
//設定點的顏色
g.setColor(new Color(r.nextInt(256),r.nextInt(256),r.nextInt(256)));
//開始畫點,實質上這是畫橢圓,將上半軸半徑,左半軸半徑設定為0就可以看成是一個點
g.drawOval(r.nextInt(width),r.nextInt(height),0,0);
}
//給客戶端響應請求
ImageIO.write(bufi, "jpg", resp.getOutputStream());
}
}
回覆列表
package com.bbs.servlet;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
public class Image extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("image/jpeg");
OutputStream out = response.getOutputStream();
response.setHeader("Pragma","No-cache");
response.setHeader("Cache-Control","no-cache");
response.setDateHeader("Expires", 0);
int width = 60, height = 20;
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// 獲取圖形上下文
Graphics g = image.getGraphics();
// 生成隨機類
Random random = new Random();
// 設定背景色
g.setColor(getRandColor(200, 250));
g.fillRect(0, 0, width, height);
// 設定字型
g.setFont(new Font("Times New Roman", Font.PLAIN, 18));
// 隨機產生155條幹擾線,使圖象中的認證碼不易被其它程式探測到
g.setColor(getRandColor(180, 200));
for (int i = 0; i < 155; i++) {
int x = random.nextInt(width);
int y = random.nextInt(height);
int xl = random.nextInt(12);
int yl = random.nextInt(12);
g.drawLine(x, y, x + xl, y + yl);
}
// 取隨機產生的認證碼(4位數字)
String sRand =setRandValue(request);
if(sRand!=null)
for (int i = 0; i < sRand.length(); i++) {
g.setColor(new Color(20 + random.nextInt(200), 20 + random
.nextInt(200), 20 + random.nextInt(200)));
// 呼叫函數出來的顏色相同,可能是因為種子太接近,所以只能直接生成
g.drawString(sRand.charAt(i) + "", 13 * i + 6, 16);
}
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
encoder.encode(image);
// 圖象生效
g.dispose();
// 輸出圖象到頁面
// ImageIO.write(image, "JPG", response.getOutputStream());
out.flush();
out.close();
}
Color getRandColor(int fc, int bc) {// 給定範圍獲得隨機顏色
Random random = new Random();
if (fc > 255)
fc = 255;
if (bc > 255)
bc = 255;
int r = fc + random.nextInt(bc - fc);
int g = fc + random.nextInt(bc - fc);
int b = fc + random.nextInt(bc - fc);
return new Color(r, g, b);
}
//48-57對應0-9;65-90對應A-Z;97-122對應a-z;
String setRandValue(HttpServletRequest request) {
Random random = new Random();
String sRand = "";
//這裡是生成驗證碼的位數
for (int i = 0; i < 4; i++) {
char c = 0;
int k = random.nextInt(3);
switch (k) {
case 0:
c = (char) (random.nextInt(10) + 48);
break;
case 1:
c = (char) (random.nextInt(26) + 65);
break;
case 2:
c = (char) (random.nextInt(26) + 97);
}
sRand += c;
}
request.getSession().setAttribute("rands", sRand);
return sRand;
}
}