验证码 订阅
验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上用验证码是现在很多网站通行的方式,我们利用比较简易的方式实现了这个功能。这个问题可以由计算机生成并评判,但是必须只有人类才能解答。由于计算机无法解答CAPTCHA的问题,所以回答出问题的用户就可以被认为是人类。 [1] 展开全文
验证码(CAPTCHA)是“Completely Automated Public Turing test to tell Computers and Humans Apart”(全自动区分计算机和人类的图灵测试)的缩写,是一种区分用户是计算机还是人的公共全自动程序。可以防止:恶意破解密码、刷票、论坛灌水,有效防止某个黑客对某一个特定注册用户用特定程序暴力破解方式进行不断的登陆尝试,实际上用验证码是现在很多网站通行的方式,我们利用比较简易的方式实现了这个功能。这个问题可以由计算机生成并评判,但是必须只有人类才能解答。由于计算机无法解答CAPTCHA的问题,所以回答出问题的用户就可以被认为是人类。 [1]
信息
具    体
区分用户是计算机或人的程序
作    用
防止恶意破解密码、论坛灌水等
中文名
验证码
外文名
CAPTCHA
验证码简介
验证码这个词最早是在2002年由卡内基梅隆大学的路易斯·冯·安、Manuel Blum、Nicholas J.Hopper以及IBM的John Langford所提出。卡内基梅隆大学曾试图申请此词使其成为注册商标, 但该申请于2008年4月21日被拒绝。一种常用的CAPTCHA测试是让用户输入一个扭曲变形的图片上所显示的文字或数字,扭曲变形是为了避免被光学字符识别(OCR, Optical Character Recognition)之类的电脑程序自动辨识出图片上的文数字而失去效果。由于这个测试是由计算机来考人类,而不是标准图灵测试中那样由人类来考计算机,人们有时称CAPTCHA是一种反向图灵测试。为了无法看到图像的身心障碍者,替代的方法是改用语音读出文数字,为了防止语音辨识分析声音,声音的内容会有杂音。 [2] 
收起全文
精华内容
下载资源
问答
  • 验证码

    万次阅读 多人点赞 2019-10-15 14:10:34
    短信验证码: import java.util.Random; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Controller; import...

    短信验证码:

     

    import java.util.Random;

     

    import javax.servlet.http.HttpServletRequest;

    import javax.servlet.http.HttpServletResponse;

     

    import org.springframework.stereotype.Controller;

    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.bind.annotation.RequestMethod;

    import org.springframework.web.bind.annotation.RequestParam;

    import org.springframework.web.bind.annotation.ResponseBody;

     

    import com.alibaba.fastjson.JSONObject;

    import com.bessky.financail.thirdparty.util.SendAliyunMessage;

    import com.bessky.financial.common.json.ResponseJson;

    import com.bessky.financial.common.util.StatusCode;

     

    import javax.servlet.http.HttpSession;

     

    /**

     * 

     * 发送验证码

     

     */

    @Controller

    @RequestMapping(value = "verifycode")

    public class VerifyCodeController

    {

     

        @RequestMapping(value = "getverifycode", method = {RequestMethod.GET})

        @ResponseBody

        public ResponseJson sendVerifYCode(HttpServletRequest request, @RequestParam("style") String style)

        {

            ResponseJson responseJson = new ResponseJson();

            try

            {

                JSONObject json = null;

                // 生成6位验证码

                String verifyCode = String.valueOf(new Random().nextInt(899999) + 100000);

                // 发送短信

                String phone = "1371********";

                responseJson = SendAliyunMessage.sendMsg(phone, verifyCode);

                if (StatusCode.SUCCESS.equals(responseJson.getStatus()))

                {

                    request.getSession().removeAttribute("verifyCode");

                    // 将验证码存到session中,同时存入创建时间

                    json = new JSONObject();

                    json.put("verifyCode", verifyCode);

                    json.put("createTime", System.currentTimeMillis());

                    // 将认证码存入SESSION

                    request.getSession().setAttribute("verifyCode", json);

                }

            }

            catch (Exception e)

            {

                e.printStackTrace();

            }

            return responseJson;

        }

    }

     

    发送短信验证码存入session,当然也可以将发送的验证码存入数据库然后从库中取出来比较。

     

    JSONObject json = (JSONObject)request.getSession().getAttribute("verifyCode");

            if(!json.getString("verifyCode").equals(verifyCode)){

                responseJson.setMessage("验证码错误");

                return responseJson;

            }

            if((System.currentTimeMillis() - json.getLong("createTime")) > 1000 * 60 * 5){

                responseJson.setMessage("验证码过期");

                return responseJson;

            }

     

    普通验证码

    web.xml中配置获取验证码servlet

    <servlet>

    <servlet-name>kaptcha</servlet-name>

    <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class>

    <init-param>

    <param-name>kaptcha.border</param-name>

    <param-value>no</param-value>

    </init-param>

    <init-param>

    <param-name>kaptcha.border.color</param-name>

    <param-value>105,179,90</param-value>

    </init-param>

    <init-param>

    <param-name>kaptcha.image.width</param-name>

    <param-value>160</param-value>

    </init-param>

    <init-param>

    <param-name>kaptcha.image.height</param-name>

    <param-value>36</param-value>

    </init-param>

    <init-param>

    <param-name>kaptcha.textproducer.font.size</param-name>

    <param-value>32</param-value>

    </init-param>

    <init-param>

    <param-name>kaptcha.session.key</param-name>

    <param-value>KAPTCHA_SESSION_KEY</param-value>

    </init-param>

    <init-param>

    <param-name>kaptcha.textproducer.char.length</param-name>

    <param-value>4</param-value>

    </init-param>

    <init-param>

    <param-name>kaptcha.textproducer.font.names</param-name>

    <param-value>Arial</param-value>

    </init-param>

    <init-param>

    <param-name>kaptcha.obscurificator.impl</param-name>

    <param-value>com.google.code.kaptcha.impl.NoGimpy</param-value>

    </init-param>

    </servlet>

    <servlet-mapping>

    <servlet-name>kaptcha</servlet-name>

    <url-pattern>/kaptcha.jpg</url-pattern>

    </servlet-mapping>

    校验验证码

     

    String key = (String) session.getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY);

     

    // 验证码校验

    if (!StringUtils.equalsIgnoreCase(captcha, key)) {

    json.setStatus(StatusCode.FAIL);

    json.setMessage(I18nUtils.getMessage("60000403"));

    return json;

    }

    滑块验证码后续更新!

    欢迎加入共同探讨

    展开全文
  • 好东西好西欧年各地验证码验证码验证码验证码
  • java验证码识别

    千次下载 热门讨论 2011-11-22 22:06:01
    java 验证码识别 ocr java 验证码识别 ocr
  • Java-SpringBoot发送验证码短信

    万次阅读 2021-01-17 21:12:04
    * 验证码需求: * 1.后台随机产生4个字符 * 2.1分钟以内只能发送1次验证码 * 3.超过1分钟,但在5分钟以内,发送的验证码依然是第一次产生的验证码字符 * 4.超过了5分钟以后,产生全新的验证码 * 前端使用什么框架先...

    发送注册验证码
    * 验证码需求:
    * 1.后台随机产生4个字符
    * 2.1分钟以内只能发送1次验证码
    * 3.超过1分钟,但在5分钟以内,发送的验证码依然是第一次产生的验证码字符
    * 4.超过了5分钟以后,产生全新的验证码
    *
    前端使用什么框架先不管
    依赖配置
    短信依赖包 redis配置,因为验证码和手机号存储在redis中
    短信平台使用的建网 sms ,http://www.smschinese.cn/ 可以免费使用5条 测试即可
    注意 配置接口的 账户名 和 密钥 每个人是不同的,复制过去记得更改
    短信签名必须要设置,不能乱设 会被屏蔽短信发不出来 切记
    短信依赖包

     <!--短信jar包-->
            <dependency>
                <groupId>commons-httpclient</groupId>
                <artifactId>commons-httpclient</artifactId>
                <version>3.1</version>
            </dependency>
    

    redis jar包

    <!--redis jar 包-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-data-redis</artifactId>
            </dependency>
    

    使用redis前,要先配置连接,在application.properties配置,记得开启redis-server

    # redis 属性信息
    ## redis数据库索引(默认为0)
    spring.redis.database=0
    ## redis服务器地址
    spring.redis.host=localhost
    ## redis服务器连接端口
    spring.redis.port=6379
    ## redis服务器连接密码(默认为空)
    ## spring.redis.password=123456
    ## 连接池最大连接数(使用负值表示没有限制)
    spring.redis.jedis.pool.max-active=8
    ## 连接池中的最大空闲连接
    spring.redis.jedis.pool.max-idle=8
    ## 连接池最大阻塞等待时间(使用负值表示没有限制)
    spring.redis.jedis.pool.max-wait=-1ms
    ## 连接池中的最小空闲连接
    spring.redis.jedis.pool.min-idle=0
    

    创建一个工具类 StrUtils.getComplexRandomString ()// 获取随机字符 位数自己输入

    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Random;
    
    /**
     * @author yaohuaipeng
     * @date 2018/10/26-16:16
     */
    public class StrUtils {
        /**
         * 把逗号分隔的字符串转换字符串数组
         *
         * @param str
         * @return
         */
        public static String[] splitStr2StrArr(String str,String split) {
            if (str != null && !str.equals("")) {
                return str.split(split);
            }
            return null;
        }
    
    
        /**
         * 把逗号分隔字符串转换List的Long
         *
         * @param str
         * @return
         */
        public static List<Long> splitStr2LongArr(String str) {
            String[] strings = splitStr2StrArr(str,",");
            if (strings == null) return null;
    
            List<Long> result = new ArrayList<>();
            for (String string : strings) {
                result.add(Long.parseLong(string));
            }
    
            return result;
        }
        /**
         * 把逗号分隔字符串转换List的Long
         *
         * @param str
         * @return
         */
        public static List<Long> splitStr2LongArr(String str,String split) {
            String[] strings = splitStr2StrArr(str,split);
            if (strings == null) return null;
    
            List<Long> result = new ArrayList<>();
            for (String string : strings) {
                result.add(Long.parseLong(string));
            }
    
            return result;
        }
    
        public static String getRandomString(int length) {
            String str = "0123456789";
            Random random = new Random();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < length; i++) {
                int number = random.nextInt(10);
                sb.append(str.charAt(number));
            }
            return sb.toString();
    
        }
    
        public static String getComplexRandomString(int length) {
            String str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
            Random random = new Random();
            StringBuffer sb = new StringBuffer();
            for (int i = 0; i < length; i++) {
                int number = random.nextInt(62);
                sb.append(str.charAt(number));
            }
            return sb.toString();
        }
    
        public static String convertPropertiesToHtml(String properties){
            //1:容量:6:32GB_4:样式:12:塑料壳
            StringBuilder sBuilder = new StringBuilder();
            String[] propArr = properties.split("_");
            for (String props : propArr) {
                String[] valueArr = props.split(":");
                sBuilder.append(valueArr[1]).append(":").append(valueArr[3]).append("<br>");
            }
            return sBuilder.toString();
        }
    
    }
    
    

    创建短信发送类 配置接口,其它类调用这个类的send方法传入手机号和发送内容即可

    
    import org.apache.commons.httpclient.Header;
    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.NameValuePair;
    import org.apache.commons.httpclient.methods.PostMethod;
    
    import java.io.IOException;
    
    public class SendMsgUtils {
        private static final String UID = "amazingwest";//这是建网SMS 上的登陆账号
        private static final String KEY = "d41d8cd98f00b204e980"; //这是密钥
    
        /**
         * 手机发送短信
         * @param phone  手机号码
         * @param context  发送短信内容
         */
        public static void send(String phone, String context) {
    
            PostMethod post = null;
            try {
                //创建Http客户端
                HttpClient client = new HttpClient();
                //创建一个post方法
                post = new PostMethod("http://utf8.api.smschinese.cn");
                //添加请求头信息
                post.addRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=utf8");//在头文件中设置转码
    
                NameValuePair[] data = {new NameValuePair("Uid", UID),
                        new NameValuePair("Key", KEY),
                        new NameValuePair("smsMob", phone),
                        new NameValuePair("smsText", context)};
                //设置请求体
                post.setRequestBody(data);
                //执行post方法
                client.executeMethod(post);
    
                //获取响应头信息
                Header[] headers = post.getResponseHeaders();
                //获取状态码
                int statusCode = post.getStatusCode();
                System.out.println("statusCode:" + statusCode);
                //循环打印头信息
                for (Header h : headers) {
                    System.out.println(h.toString());
                }
                //获取相应体
                String result = new String(post.getResponseBodyAsString().getBytes("utf8"));
                System.out.println(result); //打印返回消息状态
    
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (post != null) {
                    //关闭资源
                    post.releaseConnection();
                }
            }
        }
    
    
    }
    

    创建注册常量类,主要用来区分验证码是用来注册还是登陆或者找回密码,

    /**
     * 验证码常量
     */
    public class VerificationConstant {
    
        //用户注册常量
        public static final String USER_REG = "user_reg";
    }
    
    

    前台点击发送验证码 首先要考虑多个用户同时注册,key值不能写死

    首先根据手机号加注册标识(KEY)判断redis中值value是否存在,不存在就创建一个键,key为手机号+加注册标识,
    判断时间,就是创建redis键值对的时候就,value会加上一个当前时间戳,取value第一次创建的时间会分割value 拿当前时间戳减去第一次创建的时间戳就能得出具体的时间
    第一次创建键值 设置键的存活时间为5分钟 300秒
    发送验证码短信,前端传来手机号码,在这里进行业务逻辑判断 不需要判断手机号是否注册,这是其它类的事情 使用redisTemplate 就必须得 引入redis jar包
    StrUtils.getComplexRandomString(4) 这就是上面创建的工具类中的一个方法,创建4位字符的随机数,
    StringUtils.isEmpty 是 import org.springframework.util.StringUtils 别弄错了

    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Service;
    import org.springframework.util.StringUtils;
    
    import java.util.concurrent.TimeUnit;
    
    @Service
    public class VerificationCodeServiceImpl implements IVerificationCodeService {
    
        @Autowired
        private RedisTemplate redisTemplate;
    
        /**
         * 发送注册验证码
         * 验证码需求:
         *      1.后台随机产生4个字符
         *      2.1分钟以内只能发送1次验证码
         *      3.超过1分钟,但在5分钟以内,发送的验证码依然是第一次产生的验证码字符
         *      4.超过了5分钟以后,产生全新的验证码
         * @return
         */
        @Override
        public void sendRegisterVerificationCode(String phone) throws CustomException {
            //随机产生4个字符
            String value = StrUtils.getComplexRandomString(4);
            //在redis中通过key获取对应的值        value:时间戳
            String valueCode = (String) redisTemplate.opsForValue().get(phone + ":" + VerificationConstant.USER_REG);
            //如果不为空,就意味着验证码没有过期,依然是在5分钟以内
            if(!StringUtils.isEmpty(valueCode)){
                //开始时间戳
                String beginTimer = valueCode.split(":")[1];
    
                if(System.currentTimeMillis()-Long.valueOf(beginTimer)<=60*1000){
                   //自定义异常,自己创建一个就可以了
                    throw new CustomException("亲!一分钟以内不能发送多次验证码!!");
                }
                //证明是超过了1分钟,但依然在5分钟以内,还是用之前的验证码
                value = valueCode.split(":")[0];
            }
            //存储redis中,设置有效期是5分钟  k=phone:USER_REG  v= value:时间戳
    //        RedisUtil.set(phone:USER_REG,  value:System.currentTimeMillis(),  5MIN);
            redisTemplate.opsForValue().set(phone + ":" + VerificationConstant.USER_REG,
                    value + ":" + System.currentTimeMillis(), 5, TimeUnit.MINUTES);
            //发送手机验证码
            String context = "尊敬的用户,您的验证码为:" + value + ",请您在5分钟以内完成注册!!";
            //发送短信
    //        SendMsgUtils.send(phone, context);
            System.out.println(context);
    
    
        }
    }
    

    短信发送后返回值 说 明
    -1 没有该用户账户
    -2 接口密钥不正确 [查看密钥]
    不是账户登陆密码
    -21 MD5接口密钥加密不正确
    -3 短信数量不足
    -11 该用户被禁用
    -14 短信内容出现非法字符
    -4 手机号格式不正确
    -41 手机号码为空
    -42 短信内容为空
    -51 短信签名格式不正确
    接口签名格式为:【签名内容】
    -52 短信签名太长
    建议签名10个字符以内
    -6 IP限制
    大于0 短信发送数量
    大功告成

    展开全文
  • 这是一篇含金量很高的干货文章,国家税务总局全国增值税发票查验平台验证码识别方案和具体思路,实验结果测试了200+次,识别率达到98%以上,识别速度的话,CPU大概5-8毫秒左右,模型大概3mb。

    全国增值税发票查验平台验证码


    2020.04.30

    已经同步更新,测试网址不变


    手动置顶:验证码识别测试页面(可视化操作)

    识别率97.5%,图片接口支持手动测试,以图片形式返回结果;文本接口需要联系作者,测试额度1000次限24小时内使用。

    1.本地提交一张【90x35】大小的图片;
    2. 选择需要识别的【颜色】;
    3. 点击【提交】即可;

    在这里插入图片描述

    测试地址:
    http://152.136.207.29:19812/preview?model_name=TAX

    在这里插入图片描述
    识别速度如上图所示5毫秒左右,机器配置如下图:
    在这里插入图片描述
    可见,低配1核CPU足以支撑业务日调用1.7千万级别的负载调用,加之识别率一直是全网最高,业内不少头部的财税服务提供商都是使用笔者的版本,因保密协议不得透露合作关系,在此不举例,毕竟大多数公司都会说自己并非使用爬虫技术实现查验功能,行内人应该都知道的,可自行查证。敢在合同上写下识别率指标的不存在一丝丝水分。

    7.14 更新(验证码识别率截至15号有97.5%了其实)

    后来想想94不好看,就跑到96%了,测试次数为一万个官网请求,这样又是全网最高识别率。
    在这里插入图片描述
    在这里插入图片描述

    7.13 更新(识别率回归,初步到94%)

    由于没有更高的需求,中文字符集训练过于耗时,GPU资源也不能一直用来跑这个,决定停止训练,目前版本官网实测5千次请求,94.3%准确率。

    7.12 更新(生成器调参思路)

    最新的思路:样本生成器自动调参的方法,当然了写生成器需要有一定的技术含量,需要弄清楚哪些是变量,CSDN有位大佬写过python版本的生成器,我下载来生成了一波,发现相似度比我简书放出的钓鱼版本还低hhhh,通过预留参数接口基于给出的一张样图,生成各种参数的生成样本,自动对比生成样本和给定对照样本的相似度,取最佳参数即可获得官网算法的最佳参数,调参成本也就生成w级别的样本即可找出最佳参数,对于计算机而言1分钟不到。这样只要掌握的通用生成器,只要在一定范围内更新都不是问题。此方法过于偏门,其实就算公开了思路,但是能写出来的人估计也没几个。有钱的大公司每次更新无脑去人工打码采集样本就好了,小公司还是不要做什么发票查验了,实力劝退。

    7.6 更新(官网更新,识别率翻车到90%)

    由于官网会测试本接口,对生成参数进行算法微调,不论是字体样式,颜色配比,字符集等等都针对这CSDN的两篇文章的生成器做了对抗,由于之前训练的时候尽可能考虑到模型的泛化能力,测试接口识别率降比不大,目前仍有90%的识别率,为了保证模型的持续抗更新能力,目前在线接口已不再进行更新。

    之前技术不精,思路略显笨拙,新的模型辅助了全新的生成器算法,能更好的对抗和适应各种参数的更新,后续或会开放最新的防更新思路,如何提高模型的泛化能力,最新接口请直接联系我,白嫖勿扰。

    6.19 更新(训练和部署源码+JS逆向思路)

    有人说我文章没有干货只有思路,这里我分享一下源码,训练及部署的教程:
    https://blog.csdn.net/kerlomz/article/details/86706542

    至于国税总局的发票查验平台JS这块的逆向可以参考:
    https://blog.csdn.net/qq_35228149/article/details/106818057


    验证码分析

    如图所示:图像验证码,识别指定颜色的文字。
    在这里插入图片描述

    识别思路

    首先有几条道路可以通向罗马,这里不分先后优劣一一讲述。

    1. 颜色提取的思路,可以采用HSV/K-means聚类进行颜色的分离提取:效果如下:
      在这里插入图片描述
      弊端显而易见,会有较大的特征丢失,识别率有较大的提升瓶颈,经过测试,中英文+汉字的识别率在90%左右。
    2. 不分离颜色的思路,该方案有两种处理方法:
      (1)同时预测颜色和字符内容,这种方法看起来比较正统,但是成本较高,需要标注每张图的颜色字符内容,这个要求有多高呢,一般的打码平台是无法提供这样的结果的,打码平台只返回对应颜色的内容,只能人工标注,那么需要多少样本呢?笔者训练的识别率98的模型用了100w左右的样本。一张这样的样本标注假设需要0.1元,那么100w样本需要10w标注费用,假设0.01元,也要1w的标注费用。但是验证码高质量的人工标注几乎是不存在的,因为很多样本,人眼的识别率是不如机器的,其次,标注团队不一定都是高学历,官网使用的字符集并不一定寻常人都认识,大多不会去深究,再者,相似的汉字也是容易混淆的,一个汉字旋转之后像另一个汉字是很常见的现象,所以总而言之,总体标注的准确率大概率不会超过85%。 所以即使有钱,也不一定能获得最好的资源,这方法看起来并不可取,有一种节约成本的办法,可以通过算法生成样本,但是呢,生成的识别率英文数字还可以,中文的识别率就低的可怜了。附上生成方法:https://www.jianshu.com/p/da1b972e24f2 ,当然这个生成算法是需要修改加工的,原始算法识别率不会超过40%。综合多个维度的算法微调去和官网的算法进行碰撞匹配,才能达到最终的效果,所以在此先劝退伸手党。CSDN也有另一篇Python版的生成算法,可以自行测试,生成的图片比我这个还不像hhhh,也是需要自行修改的。
      (2)每个颜色分别训练一个模型, 这种方法看起来有点蠢,但是确实比较合适有效的办法了,可以轻松借助打码平台的返回结果标注样本。需要的颜色可以通过官网提供的字段取到,返回结果通过打码平台识别得到,这样一组合,样本就有了。这种方法的成本相对较低,样本数不变的前提下,打码价格低于人工标注的成本。不过人工打码响应平均在10-20秒之间,采集如此大量的样本数据可能要把业务都熬没了,其次还是一个认知水平问题,打码平台的打手普遍学历不高,尚有不少汉字是人不齐全的,很有可能导致样本极度不均衡,字符集不全等等,归根到底高质量的样本还是得从生成算法入手,慢慢提升模型对汉字的辨识度,笔者训练的样本用了100w。每个颜色分别训练这样成本还是下不来。四种颜色就是500w样本。官网的每次获取图片的时候颜色随机出现的概率也不一定是1/4。
      在这里插入图片描述

    (3)把所有颜色都通过颜色变换为一种颜色,整体思路同(2)。如下图,笔者将黑色转换为红色。我们只需要训练红色的图片:蓝转红、黄转红、黑转红,样本成本只有采集一种颜色的成本。看起来是目前位置最佳的方案了,事实也是如此的。但是呢,100w的总样本量对于普通人来说也是一笔不小的花销,即便有了样本能做出来也需要花费不少的时间和精力。

    有些算法工作者可能会低估样本的实际需求量,3.6k分类,中文字体小,容易混淆相似的字多,不同的角度重叠干扰都会大大增加,过于复杂的网络对性能的要求也高,为了平衡性能和准确率,足够数量的样本支撑是必须的,100w样本量其实不大,一点都不要惊讶,7月之后的版本笔者用了6k字符集做的抗更新模型,训练足足花了1周。

    不过采集样本不是单纯的接打码平台就完事了,需要经过官网判断,只有通过验证,正确的样本才保存下来。这样有效的样本对提高识别率才有帮助。
    在这里插入图片描述

    实验成果

    在这里插入图片描述
    在这里插入图片描述
    笔者实时对接官网对实验模型进行检验,结果如上图,测试了200+次,识别率达到98%以上,识别速度的话,CPU大概5-8毫秒左右,部署腾讯云1核1G服务器实测10ms-12ms,模型大概3mb。

    附上接口仅供测试,为了防止滥用,接口每天只支持请求500次(此接口已不返回文本识别结果,采用图片结果代替,请在上面提供的测试页面中测试):

    http://152.136.207.29:19812/preview

    请求地址Content-Type参数形式请求方法
    http://152.136.207.29:19812/captcha/v1application/jsonJSONPOST

    具体参数:

    参数名必选类型说明
    imageYesStringBase64 编码
    param_keyNoString颜色,red\blue\black\yellow

    请求为JSON格式,形如:
    {"image": "iVBORw0KGgoAAAANSUhEUgAAAFoAAAAjCAIAAA...base64编码后的图像二进制流", "param_key ": "blue"}

    注意:图片只能是 90x35 尺寸的原图,请勿截图

    也请勿使用 模拟浏览器 的截图获取,如果不知道如何使用协议获取验证码,可以参考这个文章的方法:
    https://blog.csdn.net/kerlomz/article/details/106793781
    若对最新的JS逆向感兴趣可以关注作者。

    若以上方法都不清楚,可以【另存为图片】,本模型针对【原图】训练。
    截图无法识别,不理解的可以先了解下深度学习 图像识别原理 ,或咨询 作者

    返回结果:

    参数名类型说明
    messageString识别结果或错误消息
    codeString状态码
    successString是否请求成功

    该返回为JSON格式,形如:
    {'uid': "9b5a6a34-9693-11ea-b6f9-525400a21e62", "message": "xxxx", "code": 0, "success": true}

    请勿恶意使用,若超出当日限制将返回:
    {'uid': "9b5a6a34-9693-11ea-b6f9-525400a21e62", 'message': '超出当日请求限制,请联系作者QQ:27009583', 'success': False, 'code': -555}

    若返回 400 则表示数据包格式有误,请检查是否符合JSON标准。
    若返回 405 则请检查确保使用POST方式请求。

    Python示例:

    import requests
    import base64
    
    with open(r"C:\1.png", "rb") as f:
        b = f.read()
    
    # param_key: black-全黑色,red-红色,blue-蓝色,yellow-黄色
    r = requests.post("http://152.136.207.29:19812/captcha/v1", json={
        "image": base64.b64encode(b).decode(), "param_key": "yellow"
    })
    print(r.json())
    
    展开全文
  • 验证码 验证码 验证码 验证码 验证码 验证码
  • 都是前端,直接打开index.html即可看到所有的:常规验证码、滑动验证码、拼图验证码、选字验证码,纯前端验证码
  • project验证码project验证码project验证码project验证码
  • 验证码识别

    2018-04-11 22:57:10
    验证码识别 验证码识别 验证码识别 验证码识别 验证码识别 验证码识别 验证码识别 验证码识别
  • 验证码插件

    2018-04-10 22:21:20
    验证码插件验证码插件验证码插件验证码插件验证码插件验证码插件
  • jsp验证码,jsp中文验证码,数字验证码,汉字验证码
  • Axure8.0-制作图片验证码

    万次阅读 多人点赞 2019-11-15 08:48:38
    图片中的验证码为数字和字母的随机组合; 点击更换验证码实现验证码的更换,验证码随机出现4位字母或数字; 验证码输入时,点击提交按钮,若验证码错误进行错误提示。 元件准备 文本框(输入验证码); 矩形框...

    需求分析

    1. 图片中的验证码为数字和字母的随机组合;
    2. 点击更换验证码实现验证码的更换,验证码随机出现4位字母或数字;
    3. 验证码输入时,点击提交按钮,若验证码错误进行错误提示。

    元件准备

    • 文本框(输入验证码);
    • 矩形框(显示生成的验证码);
    • 动态面板(提示验证码输入结果对错),并且设置三个动态面板提示状态,默认为隐藏;
    • 提交按钮;
    • 文本标签(文本提示“看不清?换一张!”)

    开始制作

      文本框输入四个字符,作为默认验证码,如下:

    在这里插入图片描述

      给文本标签添加交互,如下步骤:

    在这里插入图片描述
    将变量值设置为abcdefghijklmnopqrstuvwxyz0123456789(26个英文字母+10个数字),验证码的值将会在这36个字符中产生。

    设置好之后,不要关闭面板,继续在case1里面添加,选择设置文本,选中矩形元件,将值设为[[OnLoadVariable.substr(OnLoadVariable.length*Math.random(),1)]],并连续输入4遍,中间不需要符号,完成后点确定,如下:
    在这里插入图片描述

      接下来给按钮添加交互,先添加条件,在设置状态。设置情形一:如果输入框文字 == 验证码文字,设置面板状态为提示正确状态,且设置面板状态为可见。具体步骤如下:
    在这里插入图片描述
    在这里插入图片描述
    同理,设置情形二:如果输入框文字 != 验证码文字,设置面板状态为提示错误状态,且设置面板状态为可见。添加case2的条件并设置状态,如下:
    在这里插入图片描述
    总体设置如下:
    在这里插入图片描述

    预览效果

    在这里插入图片描述
    在这里插入图片描述

    原型地址

    >>点击查看“图片验证码”原型

    展开全文
  • JQuery验证码

    2017-11-06 17:11:21
    JQuery验证码JQuery验证码JQuery验证码JQuery验证码JQuery验证码
  • 登录验证码

    2018-11-06 15:41:04
    登录验证码 jigsawcanvas滑动验证码
  • 随机验证码随机验证码随机验证码随机验证码随机验证码
  • jq 验证码插件jq 验证码插件jq 验证码插件jq 验证码插件jq 验证码插件jq 验证码插件jq 验证码插件jq 验证码插件
  • 图形验证码

    2017-09-09 10:29:54
    图形验证码 java 动态获取图形验证码 图形验证码 java 动态获取图形验证码图形验证码 java 动态获取图形验证码
  • 使用java + selenium + OpenCV破解网易易盾滑动验证码 * 验证码地址:https://dun.163.com/trial/jigsaw * 使用OpenCv模板匹配 * Java + Selenium + OpenCV 产品样例 接下来就是见证奇迹的时刻! 注意!!! · 在...
  • 验证码算法

    2018-06-14 23:16:49
    使用Java生成验证码图片使用Java生成验证码图片使用Java生成验证码图片
  • 验证码图片

    2018-10-29 17:34:53
    可用于训练的验证码图片,数量6000+,以验证码图片实际的值命名文件,验证码为6位数。
  • java实现的汉字输入验证码,主要包含两个类,一个是生成验证码,一个是判断验证码输入是否正确,实现原理非常简单,将汉字和干扰线生成图片并将汉字保存到session,前台获取每次生成验证码图片并用文本框值和session值...
  • 验证码生成

    2018-01-30 16:22:10
    验证码生成工具类及后台控制器,保存验证码信息至session,并将验证码显示在页面指定位置,单击验证码更换。
  • 通用验证码识别-通杀验证码验证码OCR识别DLL,训练集一共20W样本,各种验证码样本训练,里面有说明文档,直接本地调用!
  • 大家知道简单数字或者字母验证码很容易被破解,但是算式验证码或者中文汉字验证码不容易被破解,所以建议大家在使用验证码的时候,尽量用算式验证码或者中文汉字验证码。 下面是我写的两种验证码代码,有用到的朋友...
  • 验证码测试

    2017-01-14 18:11:03
    PHP验证码
  • 验证码生成后是存储在session中的,使用相同的属性名(类似key)即可取出,然后进行比对 1. 验证码生成工具类 package com.jbp.util; import java.awt.*; import java.awt.image.BufferedImage; import java.util....
  • 易语言验证码模块源码,验证码模块,子程序_创建验证码画板,子程序_读验证码

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 240,764
精华内容 96,305
关键字:

验证码