程序人生丨三種語言實現(xiàn)—用戶登錄界面隨機(jī)驗證碼,源代碼分享!
以前用手機(jī)登錄不要驗證碼,現(xiàn)在登錄老要驗證碼,把人煩死!那么為什么每次登錄都有煩人的驗證碼?其實這里涉及到網(wǎng)絡(luò)完全問題!

一、應(yīng)用場景
很多伙伴應(yīng)該都知道:
防止黑客通過接口調(diào)用攻擊系統(tǒng),每次登錄系統(tǒng)要輸入驗證碼就防止機(jī)器訪問。
做限流處理,防止同一時間產(chǎn)生大量用戶的涌入,防止系統(tǒng)崩潰。
驗證碼的種類
傳統(tǒng)輸入式驗證碼: 用戶輸入圖片中的字母、數(shù)字、漢字等進(jìn)行驗證。簡單易操作,人機(jī)交互性較好。但安全系數(shù)低,容易被攻擊。
輸入式的圖形驗證碼: 有精美圖案,識別文本也清晰可認(rèn),專注于廣告。一種廣告位的展現(xiàn)形式。
純行為驗證碼: 照要求將備選碎片直線滑動到正確的位置。操作簡單,體驗好。單一維度,容易被逆向模擬,與移動端頁面切換不兼容。
圖標(biāo)選擇與行為輔助: 給出一組圖片,按要求點擊其中一張或者多張。借用萬物識別的難度阻擋機(jī)器。安全性強(qiáng)。對于圖片、圖庫、技術(shù)要求高。
點擊式的圖文驗證與行為輔助: 通過文字提醒用戶點擊圖中相同字的位置進(jìn)行驗證。操作簡單,體驗良好,單一圖片區(qū)域較大,被攻擊的難度大。
智能驗證碼: 通過行為特征、設(shè)備指紋、數(shù)據(jù)風(fēng)控等技術(shù),正常用戶免驗證,異常用戶強(qiáng)制驗證。簡單便捷,區(qū)分人與機(jī)器、人與人、設(shè)備與設(shè)備。

二、不同實現(xiàn)
下面以三種不同的編程語言,通過代碼生成驗證碼。
2.1 Java語言實現(xiàn)
先看下Java代碼是如何生成驗證碼的。手動創(chuàng)建下面這個類,就可以生成驗證碼了。代碼如下:
public class GenVerifyCodeUtils {
? ? private static char mapTable[] = {
? ? ? ? ? ? '0', '1', '2', '3', '4', '5',
? ? ? ? ? ? '6', '7', '8', '9', '0', '1',
? ? ? ? ? ? '2', '3', '4', '5', '6', '7',
? ? ? ? ? ? '8', '9'};
? ? public static void main(String[] args) {
? ? ? ? OutputStream outputStream = new BufferedOutputStream(new ByteArrayOutputStream());
? ? ? ? System.out.println(getImageCode(100,80,outputStream ));
? ? }
? ? public static Map<String, Object> getImageCode(int width, int height, OutputStream os) {
? ? ? ? Map<String,Object> returnMap = new HashMap<String, Object>();
? ? ? ? if (width <= 0) width = 60;
? ? ? ? if (height <= 0) height = 20;
? ? ? ? BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
? ? ? ? // 獲取圖形上下文
? ? ? ? Graphics g = image.getGraphics();
? ? ? ? //生成隨機(jī)類
? ? ? ? Random random = new Random();
? ? ? ? // 設(shè)定背景色
? ? ? ? g.setColor(getRandColor(200, 250));
? ? ? ? g.fillRect(0, 0, width, height);
? ? ? ? //設(shè)定字體
? ? ? ? g.setFont(new Font("Times New Roman", Font.PLAIN, 18));
? ? ? ? // 隨機(jī)產(chǎn)生168條干擾線,使圖像中的認(rèn)證碼不易被其它程序探測到
? ? ? ? g.setColor(getRandColor(160, 200));
? ? ? ? for (int i = 0; i < 168; 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);
? ? ? ? }
? ? ? ? //取隨機(jī)產(chǎn)生的碼
? ? ? ? String strEnsure = "";
? ? ? ? //4代表4位驗證碼,如果要生成更多位的認(rèn)證碼,則加大數(shù)值
? ? ? ? for (int i = 0; i < 4; ++i) {
? ? ? ? ? ? strEnsure += mapTable[(int) (mapTable.length * Math.random())];
? ? ? ? ? ? // 將認(rèn)證碼顯示到圖像中
? ? ? ? ? ? g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));
? ? ? ? ? ? // 直接生成
? ? ? ? ? ? String str = strEnsure.substring(i, i + 1);
? ? ? ? ? ? // 設(shè)置隨便碼在背景圖圖片上的位置
? ? ? ? ? ? g.drawString(str, 13 * i + 20, 25);
? ? ? ? }
? ? ? ? // 釋放圖形上下文
? ? ? ? g.dispose();
? ? ? ? returnMap.put("image",image);
? ? ? ? returnMap.put("strEnsure",strEnsure);
? ? ? ? return returnMap;
? ? }
? ? static 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);
? ? }
}
效果如下:

2.2 Javascript 實現(xiàn)
這里我也用原生Js寫了一個生成驗證碼的工具,代碼如下:
<form action="#">? ? <input type="text" id="input1" onblur="inputBlur()"/>
? ? <input type="text" onclick="createCode()" readonly="readonly" id="checkCode" class="unchanged" style="width: 80px;background: #660099"/><br />
</form>
<script language="javascript" type="text/javascript">
? var code; //在全局 定義驗證碼
? var code2; //在全局 定義驗證碼
? function createCode() {
? ? code = "";
? ? var checkCode = document.getElementById("checkCode");
? ? function RndNum(n) {
? ? ? var rnd = "";
? ? ? for (var i = 0; i < n; i++)
? ? ? ? rnd += Math.floor(Math.random() * 10);
? ? ? return rnd;
? ? }
? ? var num = RndNum(2);
? ? var num2 = RndNum(2);
? ? code = num + "+" + num2 + "=";
? ? code2 = parseInt(num) + parseInt(num2)
? ? if (checkCode) {
? ? ? checkCode.className = "code";
? ? ? checkCode.value = code;
? ? }
? }
? function inputBlur(){
? ? var inputCode = document.getElementById("input1").value;
? ? if (inputCode.length <= 0) {
? ? ? ? alert("請輸入驗證碼!");
? ? ? }
? ? ? else if (inputCode != code2) {
? ? ? ? alert("驗證碼輸入錯誤!");
? ? ? ? createCode();
? ? ? }
? ? ? else {
? ? ? ? alert("^-^ OK");
? ? ? }
? }
</script>
<style type="text/css">
? ? .code
? ? {
? ? ? font-family: Arial;
? ? ? font-style: italic;
? ? ? color: Red;
? ? ? border: 0;
? ? ? padding: 2px 3px;
? ? ? letter-spacing: 3px;
? ? ? font-weight: bolder;
? ? }
? ? .unchanged
? ? {
? ? ? border: 0;
? ? }
</style>
效果如下:

2.3 python實現(xiàn)
代碼如下:
# -*- coding: utf-8 -*
from PIL import Image, ImageDraw, ImageFont, ImageFilter
import random
# 隨機(jī)字母:
def rndChar():
? ? return chr(random.randint(65, 90))
# 隨機(jī)顏色1:
def rndColor():
? ? return (random.randint(64, 255), random.randint(64, 255), random.randint(64, 255))
# 隨機(jī)顏色2:
def rndColor2():
? ? return (random.randint(32, 127), random.randint(32, 127), random.randint(32, 127))
# 240 x 60:
width = 60 * 4
height = 60
image = Image.new('RGB', (width, height), (255, 255, 255))
# 創(chuàng)建Font對象:
font = ImageFont.truetype('C:\Windows\Fonts\Arial.ttf', 36)
# 創(chuàng)建Draw對象:
draw = ImageDraw.Draw(image)
# 填充每個像素:
for x in range(width):
? ? for y in range(height):
? ? ? ? draw.point((x, y), fill=rndColor())
# 輸出文字:
for t in range(4):
? ? draw.text((60 * t + 10, 10), rndChar(), font=font, fill=rndColor2())
# 模糊:
image = image.filter(ImageFilter.BLUR)
image.save('code.jpg', 'jpeg')
image.show()
運行效果如下圖:

三、最后
本篇講了為什么會有驗證碼這個東東,和市面上現(xiàn)在驗證碼的種類,簡單給大家做了一下科普,最后分別以不同的編程語言,展示了生成驗證碼的過程?,F(xiàn)在網(wǎng)絡(luò)安全尤為重要,驗證碼這個功能雖小,但是不可不做!
原文鏈接:https://blog.csdn.net/huaairen/article/details/106630103

學(xué)習(xí)C/C++編程知識,提升C/C++編程能力,歡迎關(guān)注UP一起來成長!
另外,UP在主頁上傳了一些學(xué)習(xí)C/C++編程的視頻教程,有興趣或者正在學(xué)習(xí)的小伙伴一定要去看一看哦!會對你有幫助的~