java验证码代码
- 格式:pdf
- 大小:142.65 KB
- 文档页数:16
⽤java实现验证码(CAPTCHA)⼀、关于验证码⾸先来说,验证码在我们的⽇常登录,发表⾔论时⽐较常见,它是⼀种⽤来区分登录⽤户是⼈还是机器的⼀种公共⾃动程序。
它可以防⽌恶意破解密码、刷票、论坛灌⽔。
⼆、⽤java来实现验证码了解了验证码的作⽤,接下来我们就⽤java来实现验证码这⼀功能。
⾸先我们先分析⼀下,怎么⽣成⼀个验证码。
我们需要⼀个BufferedImage对象来保存图⽚;通过它来获得Graphics对象;通过Randrom产⽣随机验证码信息;使⽤Graphics绘制图⽚;记录验证码信息到session中;使⽤ImageIO输出图⽚;1package com.water.servlet;23import com.sun.javafx.font.FontStrike;45import javax.imageio.ImageIO;6import javax.servlet.ServletException;7import javax.servlet.http.HttpServlet;8import javax.servlet.http.HttpServletRequest;9import javax.servlet.http.HttpServletResponse;10import java.awt.*;11import java.awt.image.BufferedImage;12import java.io.IOException;13import java.util.Random;1415public class ImgServlet extends HttpServlet {16 @Override17protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {18 BufferedImage bi = new BufferedImage(68, 22, BufferedImage.TYPE_INT_RGB);19 Graphics graphics = bi.getGraphics();20 Color color = new Color(200, 150, 255);21 graphics.setColor(color);22 graphics.fillRect(0,0,68,32);23char[] chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".toCharArray();24 StringBuffer sb = new StringBuffer();25 Random random = new Random();26for (int i = 0; i < 4; i++) {27char aChar = chars[random.nextInt(36)];28 graphics.setColor(new Color(random.nextInt(88),random.nextInt(188),random.nextInt(255)));29 graphics.drawString(aChar+"",(i*15)+3,18);30 sb.append(aChar);31 }32 req.getSession().setAttribute("charCode",sb.toString());33 ImageIO.write(bi,"jpg",resp.getOutputStream());3435 }36 }写⼀个登录页⾯来检验验证码的正确与否。
java验证⼿机号码、电话号码(包括最新的电信、联通和移动号码)⼀、⽬前的号码段(2017-06-01更新)⼆、代码package com.linbilin.test;import java.util.regex.Pattern;public class CheckPhone {/** 座机电话格式验证 **/private static final String PHONE_CALL_PATTERN = "^(?:\\(\\d{3,4}\\)|\\d{3,4}-)?\\d{7,8}(?:-\\d{1,4})?$";/*** 中国电信号码格式验证⼿机段: 133,153,180,181,189,177,1700,173* **/private static final String CHINA_TELECOM_PATTERN = "(?:^(?:\\+86)?1(?:33|53|7[37]|8[019])\\d{8}$)|(?:^(?:\\+86)?1700\\d{7}$)";/*** 中国联通号码格式验证⼿机段:130,131,132,155,156,185,186,145,176,1707,1708,1709,175* **/private static final String CHINA_UNICOM_PATTERN = "(?:^(?:\\+86)?1(?:3[0-2]|4[5]|5[56]|7[56]|8[56])\\d{8}$)|(?:^(?:\\+86)?170[7-9]\\d{7}$)";/*** 简单⼿机号码校验,校验⼿机号码的长度和1开头*/private static final String SIMPLE_PHONE_CHECK = "^(?:\\+86)?1\\d{10}$";/*** 中国移动号码格式验证* ⼿机段:134,135,136,137,138,139,150,151,152,157,158,159,182,183,184* ,187,188,147,178,1705***/private static final String CHINA_MOBILE_PATTERN = "(?:^(?:\\+86)?1(?:3[4-9]|4[7]|5[0-27-9]|7[8]|8[2-478])\\d{8}$)|(?:^(?:\\+86)?1705\\d{7}$)";/*** 仅⼿机号格式校验*/private static final String PHONE_PATTERN = new StringBuilder(300).append(CHINA_MOBILE_PATTERN).append("|").append(CHINA_TELECOM_PATTERN).append("|").append(CHINA_UNICOM_PATTERN).toString();/*** ⼿机和座机号格式校验*/private static final String PHONE_TEL_PATTERN = new StringBuilder(350).append(PHONE_PATTERN).append("|").append("(").append(PHONE_CALL_PATTERN).append(")").toString();/*** 匹配多个号码以,、或空格隔开的格式,如 177********* 133********、(596)3370653,177********,133******** (0596)3370653* @param input* @param separator 可以⾃⼰指定分隔符,如"、, "表⽰可以以顿号、逗号和空格分隔* @return*/public static boolean checkMultiPhone(String input, String separator) {separator = escapeMetacharacterOfStr(separator);String regex = "^(?!.+["+ separator+ "]$)(?:(?:(?:(?:\\(\\d{3,4}\\)|\\d{3,4}-)?\\d{7,8}(?:-\\d{1,4})?)|(?:1\\d{10}))(?:["+ separator + "]|$))+$";return match(regex, input);}/*** 转义字符串中的[]-^\元字符** @param input* @param separator* @return*/private static String escapeMetacharacterOfStr(String input) {String regex = "[-^\\[\\]\\\\]";return input.replaceAll(regex, "\\\\$0");}/*** 仅⼿机号码校验** @param input* @return*/public static boolean isPhone(String input) {return match(PHONE_PATTERN, input);}/*** ⼿机号或座机号校验** @param input* @return*/public static boolean isPhoneOrTel(String input) {System.out.println(PHONE_TEL_PATTERN);return match(PHONE_TEL_PATTERN, input);}/*** 验证电话号码的格式** @author LinBilin* @param str* 校验电话字符串* @return 返回true,否则为false*/public static boolean isPhoneCallNum(String str) {return match(PHONE_CALL_PATTERN, str);}/*** 验证【电信】⼿机号码的格式** @author LinBilin* @param str* 校验⼿机字符串* @return 返回true,否则为false*/public static boolean isChinaTelecomPhoneNum(String str) { return match(CHINA_TELECOM_PATTERN, str);}/*** 验证【联通】⼿机号码的格式** @author LinBilin* @param str* 校验⼿机字符串* @return 返回true,否则为false*/public static boolean isChinaUnicomPhoneNum(String str) { return match(CHINA_UNICOM_PATTERN, str);}/*** 验证【移动】⼿机号码的格式** @author LinBilin* @param str* 校验⼿机字符串* @return 返回true,否则为false*/public static boolean isChinaMobilePhoneNum(String str) { return match(CHINA_MOBILE_PATTERN, str);}/*** 简单⼿机号码校验,校验⼿机号码的长度和1开头** @param str* @return*/public static boolean isPhoneSimple(String str) {return match(SIMPLE_PHONE_CHECK, str);}/*** 匹配函数** @param regex* @param input* @return*/private static boolean match(String regex, String input) { return Pattern.matches(regex, input);}}。
java从几个字母中随机取值的方法全文共四篇示例,供读者参考第一篇示例:在Java编程中,有时候我们需要从一组字母中随机取值,这在一些应用中非常常见,比如密码生成器、验证码生成器等。
那么在Java 中,如何实现从一组字母中随机取值呢?接下来我将分享几种方法供大家参考。
方法一:使用Random类在Java中,我们可以使用Random类来生成随机数,通过生成的随机数的范围来确定取哪个字母。
我们可以将所有的字母存储在一个数组中,然后通过随机数生成器生成一个0到数组长度-1之间的随机数,然后取该随机数对应的字母。
```javaimport java.util.Random;Random random = new Random();int index = random.nextInt(letters.length);char randomLetter = letters[index];System.out.println("随机取值的字母为:" + randomLetter);}}```方法二:使用Math.random()方法除了使用Random类外,我们还可以使用Math.random()方法来生成一个0到1之间的随机数,然后将该随机数乘以数组长度并取整,得到一个随机索引,最终取得对应的字母。
以上便是几种在Java中实现从一组字母中随机取值的方法,大家可以根据实际需要选择适合自己的方法来实现。
希望本文对大家有所帮助,谢谢阅读!第二篇示例:在Java编程中,有时候我们需要从一组字符中随机取值。
这样的需求可能因为业务场景的特殊性而存在,比如需要生成验证码、随机密码等。
本文将介绍几种在Java中实现从一组字符中随机取值的方法。
1. 使用Math.random()方法Math类是Java中的数学工具类,其中的random()方法可以生成一个介于0.0和1.0之间的伪随机double类型的数字。
Java实现短信验证码--设置发送间隔时间,以及有效时间(Java+Redis)Java实现短信验证码--设置发送间隔时间,以及有效时间(Java+Redis)这篇⽂章,实现了Java发送⼿机短信验证码发送的间隔时间,以及⼿机验证码的有效时间和⼿机验证码格式的合法性验证,可以防⽌恶意刷接⼝代码部分package com.zxjs.controller.app;import io.swagger.annotations.Api;import io.swagger.annotations.ApiImplicitParam;import io.swagger.annotations.ApiOperation;import ng.RandomStringUtils;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.ResponseBody;import org.springframework.web.bind.annotation.RestController;import redis.clients.jedis.Jedis;import java.util.HashSet;import java.util.Set;import java.util.concurrent.Executors;import java.util.concurrent.ScheduledExecutorService;import java.util.concurrent.TimeUnit;import java.util.regex.Matcher;import java.util.regex.Pattern;/*** 发送短信验证码*/@Api(value="发送短信验证码",description = "发送短信验证码,默认发送短信的间隔是⼀分钟",tags = {"发送短信验证码"})@RestController@RequestMapping("appISendSms")public class SendSMS {private final static Logger logger = LoggerFactory.getLogger(SendSMS.class);/*** 链接redis数据库,使⽤验证码的时候,只需要在其他的地⽅⽤redis查询这个⼿机号的验证码就可以了*/static Jedis jedis = new Jedis("localhost");/*** ⽣成随机的六位验证码*/static String sale = "";/*** @param args*/public static void main(String[] args) throws InterruptedException{//⼿机号测试部分sendSmsInfo("136********");}/*** 发送验证消息* 传⼊⼿机号,接收到的是⽤户的⼿机号码* @return*/@ApiOperation(value="发送验证消息",notes = "发送验证消息,默认同⼀个⼿机号码发送短信间隔是⼀分钟,加⼊⼿机号码格式验证,可使⽤时长是五分钟,可以有效防⽌恶意刷接⼝")@ApiImplicitParam(paramType = "query",name="phone",value = "0",required = true)@GetMapping("getReCode")@ResponseBodypublic static String sendSmsInfo(String phone){//进⼊发送逻辑的时候⽣成随机验证码,六位数字sale = RandomStringUtils.randomNumeric(6);//思路,每个⼿机号进来的时候,放到redis⾥⾯⼀个值,(⼿机号,验证码+开始时间)// 当这个⽤户再次来查询的时候,查看时间是否到达⼀分钟,到达的话可以发送验证码try {//验证码有效时间,放到redis缓存⾥⾯(⼿机号,验证码+开始时间),根据开始时间来判断,达到了时间删掉缓存⾥⾯的⼿机号String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9])|(16[6]))\\d{8}$";Pattern p = pile(regex);Matcher m = p.matcher(phone);boolean isMatch = m.matches();if (! isMatch) {return "⼿机号码格式不正确,请核对后重新输⼊!";} else {/*检测redis是否开启,未开启的话,返回信息*/if(jedis.ping() == "PONG"){return "Redis Is Not Run!";}//当前时间秒数Long timemili = System.currentTimeMillis() / 1000;// System.out.println("当前的秒数" + timemili);// System.out.println(jedis.dbSize());// System.out.println(jedis.keys("*"));/*在这⾥写⼀个定时的for循环,⽤来取redis的⼿机号码信息,然后查询⼿机号码开始的时间,若是⼤于等于五分钟* 就给删除这个键值*///创建多线程定时任务,延迟1s启动,每隔1s执⾏⼀次,是前⼀个任务开始时就开始计算时间间隔,但是会等上⼀个任务结束在开始下⼀个ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(10);scheduledExecutorService.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {/*执⾏程序的位置*///⾸先取出所有的⼿机号键信息,放到新的集合⾥Set setPhone = new HashSet();setPhone = jedis.keys("*");for (Object setInfo : setPhone) {//判断这个键的值是不是超过五分钟,是的话就删除掉这个键System.out.println("计算结果"+ (System.currentTimeMillis() / 1000 - Long.parseLong(jedis.get(setInfo.toString()).substring(6))) );if(System.currentTimeMillis() / 1000 - Long.parseLong(jedis.get(setInfo.toString()).substring(6)) > 300){jedis.del(setInfo.toString());}// System.out.println(setInfo);}}}, 1, 2, TimeUnit.SECONDS);/*** 设置键值的时候先查询是否存在这个键值对,存在的话查看时长,不存在的话直接发送短信*/boolean str = jedis.exists(phone);if (! str) {//发送短息String recode = SmsInfo(phone);jedis.set(phone, (sale + timemili));return recode;} else {String strT = jedis.get(phone);//查看请求间隔,默认是⼀分钟,⼩于⼀分钟继续等待,超过⼀分钟发送短信if (timemili - Long.parseLong(strT.substring(6)) < 60) {// System.out.println("请⼀分钟后再次重试" + new Date());return "请等待⼀分钟后再次重试!";} else {//发送短息String recode = SmsInfo(phone);jedis.set(phone, (sale + timemili));return recode;}}}}catch(Exception e){logger.error(e.getMessage());}return "false";}/*** 发送短息* @return*/public static String SmsInfo(String phone){这⾥设置短信验证码的接⼝和账户密码部分(⾃⼰购买的接⼝在这⾥)String url ="/sendNSms.do";String username ="";//内容String password ="";//密码String mobile = phone; //号码String content ="您本次操作的的验证码是:"+sale+",验证码五分钟内有效,请不要把验证码发送给别⼈!";//内容String productid =""; //产品idString xh ="";//设置为空String tkey = TimeUtil.getNowTime("yyyyMMddHHmmss");try{content= URLEncoder.encode(content,"utf-8");}catch (UnsupportedEncodingException e) {e.printStackTrace();}String param="gateway="+url+"&username="+username+"&password="+ MD5Gen.getMD5(MD5Gen.getMD5(password)+tkey)+"&tkey="+tkey+"&mobile="+mobile+"&content="+content+"&productid="+productid+"&xh"+xh; // String ret= HttpRequest.sendGet(url, param);//sendPost or sendGet 即get和post⽅式System.out.println("ret:"+ret+param);return sale;}}⽤到的⼯具类的部分。
Java行为验证码1、前言验证码通常是为了区分用户是人还是计算机,也可以预防被解开密码、批量操作等恶意行为,而客户端上多数会用在关键操作上,比如购买、登录、注册等场景。
现在验证码的种类样式也特别多,今天教大家如何用Java做出验证码吧。
2、Java代码package com.kyger;import jakarta.servlet.ServletException;import jakarta.servlet.http.HttpServlet;import jakarta.servlet.http.HttpServletRequest;import jakarta.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.Map;public class demo extends HttpServlet {private static final long serialVersionUID = 1L;public demo() {super();}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 编码request.setCharacterEncoding("utf-8");response.setCharacterEncoding("utf-8");;response.setContentType("text/html; charset=utf-8");// 后台处理if (request.getMethod().equals("POST")){String html, appId, appSecret;// 设置AppId 及AppSecret,在应用管理中获取appId = "appID";appSecret = "appSecret";KgCaptchaSDK KgRequest = new KgCaptchaSDK(appId, appSecret);// 前端验证成功后颁发的token,有效期为两分钟KgRequest.token = request.getParameter("kgCaptchaToken");// 填写应用服务域名,在应用管理中获取KgRequest.appCdn = "appCdn";// 请求超时时间,秒KgRequest.connectTimeout = 5;// 用户登录或尝试帐号,当安全策略中的防控等级为3时必须填写,一般情况下可以忽略// 可以填写用户输入的登录帐号(如:request.getParameter("username"),可拦截同一帐号多次尝试等行为erId = "kgCaptchaDemo";// request 对象,当安全策略中的防控等级为3时必须填写,一般情况下可以忽略KgRequest.request = request;// java 环境中无法提供request 对象,请分别定义:clientIp|clientBrowser|domain 参数,即:// KgRequest.clientIp = ""; // 填写客户端IP// KgRequest.clientBrowser = ""; // 客户端浏览器信息// KgRequest.domain = ""; // 你的授权域名或服务IP// 发送验证请求Map<String, String> requestResult = KgRequest.sendRequest();if("0".toString().equals(requestResult.get("code"))) {// 验签成功逻辑处理***// 这里做验证通过后的数据处理// 如登录/注册场景,这里通常查询数据库、校验密码、进行登录或注册等动作处理// 如短信场景,这里可以开始向用户发送短信等动作处理// ...html = "<script>alert('验证通过');history.back();</script>";} else {// 验签失败逻辑处理html = "<script>alert(\"" + requestResult.get("msg") + " - " + requestResult.get("code") + "\");history.back();</script>";}response.getWriter().append(html);} else {response.sendRedirect("index.html");}}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doGet(request, response);}}3、效果如下4、最后以上就是java实现行为验证码的全部内容。
⽣成验证码的⼏种⽅式⽣成验证码的⼏种⽅式1,在jsp页⾯中直接⽣成验证码image.jsp源码://image.jsp<%@ page contentType="image/jpeg"import="java.awt.*,java.awt.image.*,java.util.*,javax.imageio.*"pageEncoding="GBK"%><%!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);}%><%//设置页⾯不缓存response.setHeader("Pragma", "No-cache");response.setHeader("Cache-Control", "no-cache");response.setDateHeader("Expires", 0);// 在内存中创建图象// 通过这⾥可以修改图⽚⼤⼩int width = 85, height = 23;BufferedImage image = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);// 获取图形上下⽂// g相当于笔Graphics g = image.getGraphics();//⽣成随机类Random random = new Random();// 设定背景⾊g.setColor(getRandColor(200, 250));// 画⼀个实⼼的长⽅,作为北京g.fillRect(0, 0, width, height);//设定字体g.setFont(new Font("⿊体", Font.PLAIN, 18));//画边框g.setColor(Color.BLUE);g.drawRect(0,0,width-1,height-1);// 随机产⽣155条⼲扰线,使图象中的认证码不易被其它程序探测到g.setColor(getRandColor(160, 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 rand = request.getParameter("rand");//rand = rand.substring(0,rand.indexOf("."));String sRand = "";// 如果要使⽤中⽂,必须定义字库,可以使⽤数组进⾏定义// 这⾥直接写中⽂会出乱码,必须将中⽂转换为unicode编码String[] str = { "A", "B", "C", "D", "E", "F", "G", "H", "J", "K","L", "M", "N", "P", "Q", "R", "S", "T", "U", "V", "W", "X","Y", "Z", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j","k", "m", "n", "p", "s", "t", "u", "v", "w", "x", "y", "z","1", "2", "3", "4", "5", "6", "7", "8", "9" };for (int i = 0; i < 5; i++) {String rand = str[random.nextInt(str.length)];sRand += rand;// 将认证码显⽰到图象中g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));//调⽤函数出来的颜⾊相同,可能是因为种⼦太接近,所以只能直接⽣成 g.drawString(rand, 16 * i + 6, 19);}// 将认证码存⼊SESSIONsession.setAttribute("rand", sRand);// 图象⽣效g.dispose();// 输出图象到页⾯ImageIO.write(image, "JPEG", response.getOutputStream());out.clear();out = pageContext.pushBody();%>login.jsp源码(使⽤验证码的页⾯)://使⽤验证码的页⾯login.jsp<%@ page contentType="text/html" pageEncoding="GBK"%><html><head><title>登陆页⾯</title><script>function reloadImage() {document.getElementById('identity').src = 'image.jsp?ts=' + new Date().getTime();}</script></head><body><center><%// 乱码解决request.setCharacterEncoding("GBK");%><h1>登陆程序</h1><hr><%=request.getAttribute("info") != null ? request.getAttribute("info") : ""%><form action="check.jsp" method="post">⽤户ID:<input type="text" name="mid"><br>密码:<input type="password" name="password"><br>验证码:<input type="text" name="code" maxlength="5" size="5"><img src="image.jsp" id="identity" onclick="reloadImage()" title="看不清,点击换⼀张"> <br><input type="submit" value="登陆"><input type="reset" value="重置"></form></center></body></html>效果如下:2,使⽤Servlet⽣成验证码IdentityServlet.java源码://IdentityServlet.java代码如下:package com.helloweenvsfei.servlet;import java.awt.Color;import java.awt.Font;import java.awt.Graphics2D;import java.awt.image.BufferedImage;import java.io.IOException;import java.util.Random;import javax.servlet.ServletException;import javax.servlet.ServletOutputStream;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 IdentityServlet extends HttpServlet {/****/private static final long serialVersionUID = -479885884254942306L;public static final char[] CHARS = { '2', '3', '4', '5', '6', '7', '8','9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M','N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' };public static Random random = new Random();public static String getRandomString() {StringBuffer buffer = new StringBuffer();for (int i = 0; i < 6; i++) {buffer.append(CHARS[random.nextInt(CHARS.length)]);}return buffer.toString();}public static Color getRandomColor() {return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));}public static Color getReverseColor(Color c) {return new Color(255 - c.getRed(), 255 - c.getGreen(), 255 - c.getBlue());}public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {response.setContentType("image/jpeg");String randomString = getRandomString();request.getSession(true).setAttribute("randomString", randomString);int width = 100;int height = 30;Color color = getRandomColor();Color reverse = getReverseColor(color);BufferedImage bi = new BufferedImage(width, height,BufferedImage.TYPE_INT_RGB);Graphics2D g = bi.createGraphics();g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 16));g.setColor(color);g.fillRect(0, 0, width, height);g.setColor(reverse);g.drawString(randomString, 18, 20);for (int i = 0, n = random.nextInt(100); i < n; i++) {g.drawRect(random.nextInt(width), random.nextInt(height), 1, 1);}// 转成JPEG格式ServletOutputStream out = response.getOutputStream();JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);encoder.encode(bi);out.flush();}public static void main(String[] args) {System.out.println(getRandomString());}}Web..xml源码://Web.xml的配置为:<servlet><servlet-name>IdentityServlet</servlet-name><servlet-class>com.helloweenvsfei.servlet.IdentityServlet</servlet-class></servlet><servlet-mapping><servlet-name>IdentityServlet</servlet-name><url-pattern>/servlet/IdentityServlet</url-pattern></servlet-mapping>identity.html源码://测试页⾯identity.html为:<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><title>identity.html</title><meta http-equiv="keywords" content="keyword1,keyword2,keyword3"><meta http-equiv="description" content="this is my page"><meta http-equiv="content-type" content="text/html; charset=GB18030"><!--<link rel="stylesheet" type="text/css" href="./styles.css">--></head><body><script>function reloadImage() {document.getElementById('btn').disabled = true;document.getElementById('identity').src='servlet/IdentityServlet?ts=' + new Date().getTime(); }</script><img src="servlet/IdentityServlet" id="identity" onload="btn.disabled = false; "/> <input type=button value=" 换个图⽚ " onclick="reloadImage()" id="btn"></body></html>3,在Struts2应⽤中⽣成验证码RandomNumUtil.java源码://RandomNumUtil.javapackage org.ml.util;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.image.BufferedImage;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.util.Random;import javax.imageio.ImageIO;import javax.imageio.stream.ImageOutputStream;public class RandomNumUtil {public static final char[] CHARS = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M','N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z','2', '3', '4', '5', '6', '7', '8','9','a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'm','n', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};private ByteArrayInputStream image;// 图像private String str;// 验证码/*** 构造⽅法调⽤初始化属性⽅法*/private RandomNumUtil() {init();}/*** 取得RandomNumUtil实例*/public static RandomNumUtil Instance() {return new RandomNumUtil();}/*** 取得验证码图⽚*/public ByteArrayInputStream getImage() {return this.image;}/*** 取得图⽚的验证码*/public String getString() {return this.str;}/*** 初始化属性否具体⽅法*/private void init() {// 在内存中创建图象int width = 85, height = 18;//设置图形的⾼度和宽度,以及RGB类型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));// 随机产⽣255条⼲扰线,使图象中的认证码不易被其它程序探测到g.setColor(getRandColor(160, 200));for (int i = 0; i < 255; 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);}// 取随机产⽣的认证码(6位数字)StringBuffer sRand = new StringBuffer();for (int i = 0; i < 6; i++) {String rand = String.valueOf(CHARS[random.nextInt(CHARS.length-1)]);//从字符数组中随机产⽣⼀个字符sRand.append(rand);// 将认证码显⽰到图象中g.setColor(new Color(20 + random.nextInt(110), 20 + random.nextInt(110), 20 + random.nextInt(110)));// 调⽤函数出来的颜⾊相同,可能是因为种⼦太接近,所以只能直接⽣成g.drawString(rand, 13 * i + 6, 17);}// 赋值验证码this.str = sRand.toString();// 图象⽣效g.dispose();//下⾯将⽣成的图形转变为图⽚ByteArrayOutputStream output = new ByteArrayOutputStream();ByteArrayInputStream input = null;try {ImageOutputStream imageOut = ImageIO.createImageOutputStream(output);ImageIO.write(image, "JPEG", imageOut);//将图像按JPEG格式写⼊到imageOut中,即存⼊到output的字节流中 imageOut.close();//关闭写⼊流input = new ByteArrayInputStream(output.toByteArray());//input读取output中的图像信息} catch (Exception e) {System.out.println("验证码图⽚产⽣出现错误:" + e.toString());}this.image = input;/* 赋值图像 */}/** 给定范围获得随机颜⾊*/private 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);}}RandomAction.java源码://RandomAction.java的代码:package org.ml.action;import java.io.ByteArrayInputStream;import org.ml.util.RandomNumUtil;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ActionSupport;@SuppressWarnings("serial")public class RandomAction extends ActionSupport {private ByteArrayInputStream inputStream;public String execute() throws Exception {RandomNumUtil rdnu = RandomNumUtil.Instance();//取得随机验证码产⽣类的对象this.setInputStream(rdnu.getImage());// 取得带有随机字符串的图⽚ActionContext.getContext().getSession().put("random", rdnu.getString());// 取得随机字符串放⼊HttpSession return SUCCESS;}public void setInputStream(ByteArrayInputStream inputStream) {this.inputStream = inputStream;}public ByteArrayInputStream getInputStream() {return inputStream;}}struts.xml配置://struts.xml配置为:<!-- Random验证码 --><action name="rand" class="org.ml.action.RandomAction"><result type="stream" name="success"><param name="contentType">image/JPEG</param><param name="inputName">inputStream</param></result></action>HTML中的表单源码://HTML中的表单代码为:<tr height="35"><td width="14%" class="top_hui_text"><span class="login_txt">验证码:</span></td><td colspan="2" class="top_hui_text"><input type="text" name="rand" id="rand" size="6"maxlength="6"><script type="text/javascript">function changeValidateCode(obj) {//获取当前的时间作为参数,⽆具体意义var timenow = new Date().getTime();//每次请求需要⼀个不同的参数,否则可能会返回同样的验证码//这和浏览器的缓存机制有关系,也可以把页⾯设置为不缓存,这样就不⽤这个参数了。
Java认证ADFS的代码什么是ADFS?ADFS(Active Directory Federation Services)是由微软提供的一种身份验证和授权解决方案。
它允许用户使用他们在一个组织中的网络凭据来访问另一个组织的应用程序或服务。
ADFS基于标准的SAML(Security Assertion Markup Language)协议,为不同组织之间的身份验证提供了一种安全的方式。
Java认证ADFS的步骤要在Java中认证ADFS,我们需要按照以下步骤进行操作:1.创建一个Java项目并导入所需的依赖项。
我们将使用Spring Security和OpenSAML库来处理ADFS认证和SAML协议。
2.配置Spring Security以使用ADFS作为身份验证提供程序。
这包括定义ADFS的元数据和身份提供者的URL。
3.创建一个登录页面,让用户输入他们的凭据。
4.在用户输入凭据后,Java代码将使用OpenSAML库生成一个SAML请求,并将其发送到ADFS身份提供者。
5.ADFS将验证用户的凭据,并生成一个包含用户身份信息的SAML响应。
6.Java代码将验证ADFS生成的SAML响应,并提取用户的身份信息。
7.如果身份验证成功,Java代码将授予用户访问应用程序或服务的权限。
配置Spring Security首先,我们需要在Spring Security配置文件中添加ADFS作为身份验证提供程序。
以下是一个示例配置文件的片段:spring:security:saml2:metadata-url:entity-id:require-https: trueregistration:your-app:provider:signing:key:alias: your-app-keystore-password: your-app-passwordkey-password: your-app-password在这个配置文件中,我们指定了ADFS的元数据URL、我们应用程序的实体ID以及与ADFS通信所需的证书信息。
验证码VerifyCode VerifyCode.java:1 package com.xjs.image;23 import java.awt.BasicStroke;4 import java.awt.Color;5 import java.awt.Font;6 import java.awt.Graphics2D;7 import java.awt.image.BufferedImage;8 import java.io.IOException;9 import java.io.OutputStream;10 import java.util.Random;1112 import javax.imageio.ImageIO;1314public class VerifyCode {15private int w = 70;16private int h = 35;17private Random r = new Random();18// {"宋体", "华⽂楷体", "⿊体", "华⽂新魏", "华⽂⾪书", "微软雅⿊", "楷体_GB2312"}19private String[] fontNames = {"宋体", "华⽂楷体", "⿊体", "微软雅⿊", "楷体_GB2312"};20// 可选字符21private String codes = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ"; 22// 背景⾊23private Color bgColor = new Color(255, 255, 255);24// 验证码上的⽂本25private String text ;2627// ⽣成随机的颜⾊28private Color randomColor () {29int red = r.nextInt(150);30int green = r.nextInt(150);31int blue = r.nextInt(150);32return new Color(red, green, blue);33 }3435// ⽣成随机的字体36private Font randomFont () {37int index = r.nextInt(fontNames.length);38 String fontName = fontNames[index];//⽣成随机的字体名称39int style = r.nextInt(4);//⽣成随机的样式, 0(⽆样式), 1(粗体), 2(斜体), 3(粗体+斜体)40int size = r.nextInt(5) + 24; //⽣成随机字号, 24 ~ 2841return new Font(fontName, style, size);42 }4344// 画⼲扰线45private void drawLine (BufferedImage image) {46int num = 3;//⼀共画3条47 Graphics2D g2 = (Graphics2D)image.getGraphics();48for(int i = 0; i < num; i++) {//⽣成两个点的坐标,即4个值49int x1 = r.nextInt(w);50int y1 = r.nextInt(h);51int x2 = r.nextInt(w);52int y2 = r.nextInt(h);53 g2.setStroke(new BasicStroke(1.5F));54 g2.setColor(Color.BLUE); //⼲扰线是蓝⾊55 g2.drawLine(x1, y1, x2, y2);//画线56 }57 }5859// 随机⽣成⼀个字符60private char randomChar () {61int index = r.nextInt(codes.length());62return codes.charAt(index);63 }6465// 创建BufferedImage66private BufferedImage createImage () {67 BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);68 Graphics2D g2 = (Graphics2D)image.getGraphics();69 g2.setColor(this.bgColor);70 g2.fillRect(0, 0, w, h);71return image;72 }7374// 调⽤这个⽅法得到验证码75public BufferedImage getImage () {76 BufferedImage image = createImage();//创建图⽚缓冲区77 Graphics2D g2 = (Graphics2D)image.getGraphics();//得到绘制环境78 StringBuilder sb = new StringBuilder();//⽤来装载⽣成的验证码⽂本79// 向图⽚中画4个字符80for(int i = 0; i < 4; i++) {//循环四次,每次⽣成⼀个字符81 String s = randomChar() + "";//随机⽣成⼀个字母82 sb.append(s); //把字母添加到sb中83float x = i * 1.0F * w / 4; //设置当前字符的x轴坐标84 g2.setFont(randomFont()); //设置随机字体85 g2.setColor(randomColor()); //设置随机颜⾊86 g2.drawString(s, x, h-5); //画图87 }88this.text = sb.toString(); //把⽣成的字符串赋给了this.text89 drawLine(image); //添加⼲扰线90return image;91 }9293// 返回验证码图⽚上的⽂本94public String getText () {95return text;96 }9798// 保存图⽚到指定的输出流99public static void output (BufferedImage image, OutputStream out)100 throws IOException {101 ImageIO.write(image, "JPEG", out);102 }103 }测试:1 import java.awt.image.BufferedImage;2 import java.io.FileNotFoundException;3 import java.io.FileOutputStream;4 import java.io.IOException;56 import org.junit.Test;78public class Demo {9 @Test10public void fun1() throws FileNotFoundException, IOException{11 VerifyCode vc=new VerifyCode();12 BufferedImage bi=vc.getImage();//得到验证码图⽚,是⼀个BufferedImage类型的13 VerifyCode.output(bi, new FileOutputStream("F://VerifyCode.jpg"));1415 System.out.println(vc.getText());16 }17 }运⾏后会在指定⽂件路径下⽣成⼀张图⽚,以及在控制台打印图⽚上的⽂本。
⼀步步实现滑动验证码(拼图验证码),Java图⽚处理关键代码 最近滑动验证码在很多⽹站逐步流⾏起来,⼀⽅⾯对⽤户体验来说,⽐较新颖,操作简单,另⼀⽅⾯相对图形验证码来说,安全性并没有很⼤的降低。
当然到⽬前为⽌,没有绝对的安全验证,只是不断增加攻击者的绕过成本。
接下来分析下滑动验证码的核⼼流程:1. 后端随机⽣成抠图和带有抠图阴影的背景图⽚,后台保存随机抠图位置坐标2. 前端实现滑动交互,将抠图拼在抠图阴影之上,获取到⽤户滑动距离值,⽐如以下⽰例3. 前端将⽤户滑动距离值传⼊后端,后端校验误差是否在容许范围内。
这⾥单纯校验⽤户滑动距离是最基本的校验,出于更⾼的安全考虑,可能还会考虑⽤户滑动的整个轨迹,⽤户在当前页⾯的访问⾏为等。
这些可以很复杂,甚⾄借助到⽤户⾏为数据分析模型,最终的⽬标都是增加⾮法的模拟和绕过的难度。
这些有机会可以再归纳总结常⽤到的⽅法,本⽂重点集中在如何基于Java来⼀步步实现滑动验证码的⽣成。
可以看到,滑动图形验证码,重要有两个图⽚组成,抠块和带有抠块阴影的原图,这⾥⾯有两个重要特性保证被暴⼒破解的难度:抠块的形状随机和抠块所在原图的位置随机。
这样就可以在有限的图集中制造出随机的、⽆规律可寻的抠图和原图的配对。
⽤代码如何从⼀张⼤图中抠出⼀个有特定随机形状的⼩图呢?第⼀步,先确定⼀个抠出图的轮廓,⽅便后续真正开始执⾏图⽚处理操作图⽚是有像素组成,每个像素点对应⼀种颜⾊,颜⾊可以⽤RGB形式表⽰,外加⼀个透明度,把⼀张图理解成⼀个平⾯图形,左上⾓为原点,向右x轴,向下y轴,⼀个坐标值对应该位置像素点的颜⾊,这样就可以把⼀张图转换成⼀个⼆维数组。
基于这个考虑,轮廓也⽤⼆维数组来表⽰,轮廓内元素值为1,轮廓外元素值对应0。
这时候就要想这个轮廓形状怎么⽣成了。
有坐标系、有矩形、有圆形,没错,⽤到数学的图形函数。
典型⽤到⼀个圆的函数⽅程和矩形的边线的函数,类似:(x-a)²+(y-b)²=r²中,有三个参数a、b、r,即圆⼼坐标为(a,b),半径r。
java短信防刷方法在Java中防止短信防刷攻击是一项具有挑战性的任务。
这主要是因为短信服务通常是通过第三方供应商提供的,我们只能在应用程序级别进行限制和防范。
在本文中,我将向您展示如何使用Java编写代码来防止短信防刷攻击,并提供一种可行的解决方案。
1.了解短信防刷攻击在开始编写代码之前,我们需要先了解短信防刷攻击的基本概念。
短信防刷攻击是指恶意用户或者恶意代码通过发送大量的短信来消耗系统资源,造成拒绝服务攻击。
通常,攻击者使用大量的手机号码发送短信,从而避免被系统阻止。
2.实现限速功能为了防止短信防刷攻击,我们可以实现一个限速功能,限制相同手机号发送短信的频率。
这样,即使攻击者使用多个手机号,他们也无法发送过多的短信。
我们可以按照以下步骤来实现限速功能:-创建一个存储手机号和发送时间的数据结构,可以使用一个集合或者一个数据库表来存储。
-当用户发送短信时,首先检查该手机号在数据结构中是否存在。
-如果存在,则检查发送时间是否超过限制时间间隔。
如果超过限制时间,则可以允许发送短信,并更新发送时间为当前时间。
-如果发送时间未超过限制时间,则禁止发送短信,并返回错误信息。
-如果手机号在数据结构中不存在,则添加该手机号及发送时间到数据结构中,并允许发送短信。
这样,我们通过限制相同手机号发送短信的频率,可以有效地防止短信防刷攻击。
3.添加IP限制除了限制发送短信的频率,我们还可以添加IP限制,限制相同IP 发送短信的数量。
通过添加IP限制,我们可以限制恶意用户使用不同手机号发送大量的短信。
为了实现IP限制,我们可以按照以下步骤进行操作:-获取客户端请求的IP地址。
-创建一个存储IP地址和发送短信数量的数据结构。
-当用户发送短信时,首先根据IP地址检查该IP地址在数据结构中是否存在。
-如果存在,则检查发送短信的数量是否超过限制。
如果超过限制,则禁止发送短信,并返回错误信息。
-如果发送短信的数量未超过限制,则允许发送短信,并更新发送短信的数量。