精华内容
下载资源
问答
  • 在连续干了好几茬之后,硅星人突然醒悟:我这哪里是在填验证码,根本就是在帮别人标注数据,训练AI啊! 不管是给图片分类: 给路牌勾边: 还是把路牌圈出来: 感觉都是在教无人驾驶的AI认路啊…… 其实,“输验证码...

    最近,硅星人发现,上网遇见的验证码“越来越有内容”了。

    为了证明自己是个真人,除了要输入方框里的文字,还得做从下面图中挑出路牌、挑出门牌这种连连看似的高级任务。

    在连续干了好几茬之后,硅星人突然醒悟:我这哪里是在填验证码,根本就是在帮别人标注数据,训练AI啊!

    不管是给图片分类:

    给路牌勾边:

    还是把路牌圈出来:

    感觉都是在教无人驾驶的AI认路啊……

    其实,“输验证码就是在为AI打工”并不是硅星人想得太多。事实上,我们在输验证码时义务劳动的历史,从古早的文字验证码时期就开始了。

    每次输入验证码,你都在义务劳动

    今天,应用最广的验证码系统就是reCAPTCHA(Completely Automated PublicT uring Test To Tell Computers and Humans Apart,区分人机的全自动图灵测试系统)了。

    这家如今已被Google收购的公司,承担了世界上大部分网络的人机验证工作(上文给出的三个例子均来自reCAPTCHA)。

    2007年,reCAPTCHA的创始人之一,卡内基梅隆大学教授路易斯·冯·安(Luisvon Ahn)想到:“如果人类与机器各有擅长,能不能利用验证码系统,让人类和机器共同解决问题呢?”

    当时,一个亟待解决的问题就是,如何把浩如烟海的人类纸质典籍数字化。

    想要数字化文本,一种方法是手工录入。这种方法费时费力,还容易出现录入错误。另一种方法是先扫描文本,再结合光学文字识别技术录入文字。听起来很美,但有些年代久远或本身质量就差的文本扫描出来后实在是太糊了……

    以至于电脑识别出来的文本漏洞百出,根本没法看。

    为了解决文本数字化的问题,2007年,路易斯推出了新的验证码系统reCAPTCHA。

    在 reCAPTCHA验证码系统里,一个验证码会由两部分构成。

    第一部分和之前一样,是自动生成并且经过变形处理的文字,用来检验你是不是真人。而第二部分,则是从无法识别的文本中截取出来的词。

    如果用户正确输入前半部分,那么 reCAPTCHA就会假设用户输入的后半部分也是正确的,然后把录入结果返回至reCAPTCHA的项目主机。

    结果返回主机后,主机还会把这个结果再派发给多个用户进行交叉验证,以确保没有不小心或故意输错单词的情况。

    也就是说,真正有效的人机测试在验证码的前半段已经完成,而后半段,就是用户在义务为人类文明做贡献了。

    那么,reCAPTCHA到底做了多大贡献呢?

    2007年推出之初,reCAPTCHA每天都能帮助录入3000万个字符。2008年,这个数字飙升到了6000万个。粗略统计,在今天,全世界每天都有2亿个字符通过 reCAPTCHA录入,相当于人类15万小时的工作量。

    也就是说,一个人要不吃不喝不睡连轴转两年半,才能完成 reCAPTCHA一天的工作量。

    到今天为止, reCAPTCHA已经录入了从1851年至今的所有《纽约时报》,共计1300万篇文章。除《纽约时报》外,reCAPTCHA还数字化了超过2500万本书,而全球的图书数量约为1.3亿本。

    路易斯在接受媒体TheHustle采访时这样评价 reCAPTCHA:“我创造了一个系统,以十秒为单位,数百万小时为增量,来利用世界上最宝贵的资源:人的大脑。”

    验证码是在剥削我们么?

    如果reCAPTCHA的故事到这里就结束了,每个人都会很开心。但事情没那么简单。

    2009年,Google以大约2780万美元的价格收购了 reCAPTCHA,并开始利用 reCAPTCHA帮助标注数据。

    正如前文所说,reCAPTCHA的前半段是在验证你是不是真人,后半段就是真人为验证码打工阶段了。

    2012年,Google开始把Google街景中难以识别的门牌和路牌加入验证码,请用户帮忙标注。

    除了标注门牌路牌,让用户帮忙给数据库分类也是常见的形式之一。比如下图这种请用户“挑出所有有猫的图片”的验证码。

    如今,Google AI已经能精确辨认路牌上的文字和数字,准确度和人眼不相上下。

    当有一天我们终于用上Google的自动驾驶技术,依靠AI来辨识路牌和路灯时,这背后不能不说没有上千万用户无偿标注的苦劳。

    对于这一目的,Google也并不避讳。在 reCAPTCHA官网上,Google公开说明了 reCAPTCHA集众人之力标注数据、训练AI的“众包”模式。

    但是仍有用户对这一点感到不满。

    一位觉得验证码不道德的Reddit用户写到:“这就好像让几百万个人每人为你干5秒钟活儿,然后一分钱都不给一样,这合适么!”

    验证码的前世今生

    验证码提出之初,是为了解决一个特别实在的问题。

    网络世界这么大,你怎么知道网线另一端是不是一条狗(或者机器人)?

    在公开版面上,刷评机器人可以用大量垃圾评论和广告淹没真人用户留下的有价值的信息;在金融交易平台,脚本程序可以靠不停试验来暴力破解密码;在票务网站,我敢说你就算有十只手也抢不过自动刷票的黄牛……

    如何确定网络请求是真人发送的,成了维护网络环境和保护用户安全的大问题。

    2002年,正是路易斯·冯·安提出了一种切实可行的解决方案,能分清网线对面“是人是狗”。

    虽然计算机的算数和分析能力比人类强得多,但是当时的计算机连“一只小猫在奔跑”这种难不倒三岁小孩儿的图都认不出来。基于这种思想,路易斯和其他同事合作开发了reCAPTCHA的祖宗 CAPTCHA,也就是我们俗称的验证码。

    初代验证码一般是一些经过扭曲变形的文字或数字。人类可以识别这些文字(尽管偶尔也会出现连人类也认不出的情况),但机器难以理解字符的含义。

    之后,验证码也经历了算数题、选择题,甚至植入广告等类型的迭代,但都掩盖不住一个最致命的问题:虽然 CAPTCHA已经是相对比较好的解决方案,但也并非铁板一块。

    通过撞库、人工智能识别图像、甚至是把验证码图片返回给人工再批量输入等方法,黑客们总能为垃圾脚本找到可乘之机。

    更别提有些验证码,连真人都搞不定!

    附加题:请点击图中所有的范伟

    正因为验证码浪费时间,辨识难度大,而且对于执行某些特定行为(比如爬数据或做学术研究)的人类用户而言极不友好,验证码长期在“互联网时代最烦人发明”榜上名列前茅。

    于是, reCAPTCHA推出了更科学的验证系统。这种验证系统会检测用户的客户端环境,追踪用户的鼠标和键盘操作轨迹,提高了机器人的模拟成本。用户再也不需要苦哈哈地识别歪歪扭扭的文字,只需要在对话框里点击“我不是机器人”,就能通过验证。

    展开全文
  • 二像百度贴吧未登录发贴要输入验证码大概是防止大规模匿名回帖的发生目前,不少网站为了防止用户利用机器人自动注册、登录、灌水,都采用了验证码技术。所谓验证码,就是将一串随机产生的数字或符号,生成一幅图片,...

    (1).验证码一般是防止批量注册的,人眼看起来都费劲,何况是机器。二像百度贴吧未登录发贴要输入验证码大概是防止大规模匿名回帖的发生目前,不少网站为了防止用户利用机器人自动注册、登录、灌水,都采用了验证码技术。所谓验证码,就是将一串随机产生的数字或符号,生成一幅图片, 图片里加上一些干扰象素(防止OCR),由用户肉眼识别其中的验证码信息,输入表单提交网站验证,验证成功后才能使用某项功能。
    (2).一般注册用户ID的地方以及各大论坛都要要输入验证码
    (3).常见的验证码
    1,四位数字,随机的一数字字符串,最原始的验证码,验证作用几乎为零。

    2,CSDN网站用户登录用的是GIF格式,目前常用的随机数字图片验证码。图片上的字符比较中规中矩,验证作用比上一个好。没有基本图形图像学知识的人,不可破!可惜读取它的程序,在CSDN使用它的第一天,好像就在论坛里发布了,真是可怜!
    3,QQ网站用户登录用的是PNG格式,图片用的随机数字+随机大写英文字母,整个构图有点张扬,每刷新一次,每个字符还会变位置呢!有时候出来的图片,人眼都识别不了,厉害啊…

    4,MS的hotmail申请时候的是BMP格式, 随机数字+随机大写英文字母+随机干扰像素+随机位置。
    5,Google的Gmail注册时候的是JPG格式,随机英文字母+随机颜色+随机位置+随机长度。6,其他各大论坛的是XBM格式,内容随机。
    (4)意义:不少网站为了防止用户利用机器人自动注册、登录、灌水,都采用了验证码技术。所谓验证码,就是将一串随机产生的数字或符号,生成一幅图片,图片里加上一些干扰象素(防止OCR),由用户肉眼识别其中的验证码信息,输入表单提交网站验证,验证成功后才能使用某项功能。

    展开全文
  • 为什么回帖要填验证码,为什么你们的ID那么霸气,我的就是u开头[img=https://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/003/monkey/11.gif][/img]
  • 自动入短信验证码

    2019-04-10 16:50:54
    一些注重用户体验的App会在收到验证码后自动帮用户入,免去了用户手动输入验证码的烦恼,整个注册过程用户是非常Happy的。 下面我们来实现这个功能,其实逻辑流程很简单: 创建广播接收器,拦截...

    这段时间太忙了,以至于一直没有时间更新博客。正好今天公司项目需要加入自动识别验证码的功能,所以特此记录一下

    现在几乎任何App注册都离不开手机号,如果选择使用手机号注册,必定会接收并填入验证码进行注册。一些注重用户体验的App会在收到验证码后自动帮用户填入,免去了用户手动输入验证码的烦恼,整个注册过程用户是非常Happy的。

    下面我们来实现这个功能,其实逻辑流程很简单:

    1. 创建广播接收器,拦截短信
    2. 判断是不是本应用需要的验证码短信,若是便继续,否则忽略
    3. 提取验证码,通过回调接口返回给Activity/Fragment

    第一步:创建广播接收器

    由于我们只需要在注册界面对短信进行拦截,因此采用动态注册的方式。首先编写广播接收器:

    public class SMSBroadcastReceiver extends BroadcastReceiver {
    
        public static final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
        
        //回调接口
        private OnAuthCodeReceiver mOnAuthCodeReceiver;
        
    	//利用正则表达式预编译功能
        private static final Pattern AUTH_CODE_PATTERN = Pattern.compile("\\d{6}");
    
        //识别是否是本APP需要的验证码短信的关键字
        private final String SMS_KEYWORD = "小猪科技";
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (SMS_RECEIVED_ACTION.equals(intent.getAction()) &&
                    intent.getExtras() != null) {
                Object[] pdus = (Object[]) intent.getExtras().get("pdus");
                String format = intent.getStringExtra("format");
                SmsMessage smsMessage = null;
                for (Object pdu : pdus) {
                    if (Build.VERSION.SDK_INT < 23) {
                        smsMessage = SmsMessage.createFromPdu((byte[]) pdu);
                    } else {
                        smsMessage = SmsMessage.createFromPdu((byte[]) pdu, format);
                    }
                }
                if (smsMessage == null) {
                    return;
                }
                String content = smsMessage.getDisplayMessageBody();
                if (content.contains(SMS_KEYWORD) && mOnAuthCodeReceiver != null) {
                    mOnAuthCodeReceiver.onReceiver(getAuthCode(content));
                    abortBroadcast();
                }
            }
        }
    
        private String getAuthCode(String content) {
            Matcher matcher = AUTH_CODE_PATTERN.matcher(content);
            if (matcher.find()) {
                return matcher.group();
            } else {
                return "";
            }
        }
    
        public void setOnAuthCodeReceiverListener(OnAuthCodeReceiver receiver) {
            this.mOnAuthCodeReceiver = receiver;
        }
    
        public interface OnAuthCodeReceiver {
            void onReceiver(String code);
        }
    }
    

    以上代码都是一些常规获取短信内容的操作,没有什么技术含量,唯一注意一下就是这个正则获取的是6位数的验证码。

    第二步:动态注册广播

    在注册界面,动态注册广播,并在注册界面销毁时,解除注册:

    public class RegisterActivity extends AppCompatActivity {
    	private EditText etAuthCode;
    	private SMSBroadcastReceiver mSMSBroadcastReceiver = new SMSBroadcastReceiver();
    	
    	@Override
        protected void onCreate(@Nullable Bundle savedInstanceState) {
        	super.onCreate(savedInstanceState);
        	etAuthCode = findViewById(R.id.et_auth_code);
        	registerSMSReceiver();
        }
    
        private void registerSMSReceiver() {
            IntentFilter intentFilter =
                    new IntentFilter(SMSBroadcastReceiver.SMS_RECEIVED_ACTION);
            intentFilter.setPriority(Integer.MAX_VALUE);
            registerReceiver(mSMSBroadcastReceiver, intentFilter);
    
            mSMSBroadcastReceiver.setOnAuthCodeReceiverListener(
            	code -> etAuthCode.setText(code)
            );
        }
        
        @Override
        protected void onDestroy() {
            super.onDestroy();
            unregisterReceiver(mSMSBroadcastReceiver);
        }
    }
    

    最后别忘了在清单文件中加入权限:

    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    
    展开全文
  • 图片验证码

    2011-11-19 09:02:37
    实现网页注册时要填验证码的地方。 引用验证码图片" ImageUrl="~/ValidCode.ashx" /> 复制过去文件。就可用。好资源不解释。
  • android读取短信验证码自动入,简单的实现
  • Android 短信验证码自动

    Android 短信验证码自动填入

    下载地址:https://download.csdn.net/download/qq_31939617/11367198

    MainActivity .class

    package com.ryan.smscontentobsever;
    
    import android.Manifest;
    import android.content.Context;
    import android.content.pm.PackageManager;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Handler;
    import android.os.Message;
    import android.support.annotation.NonNull;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.content.ContextCompat;
    import android.support.v7.app.AppCompatActivity;
    import android.widget.EditText;
    import android.widget.Toast;
    
    public class MainActivity extends AppCompatActivity {
    
        public static final int SMS_CODE = 1;
        public static final int READ_SMS_PERMISSION = 2;
    
        private EditText mSmsCode;
        private SMSContentObserver smsContentObserver;
    
        Handler mHandler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case SMS_CODE:
                        mSmsCode.setText(msg.obj.toString());
                        break;
                    default:
                        break;
                }
    
            }
        };
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            mSmsCode = (EditText) findViewById(R.id.smsCode);
            checkPermissionsAndRegisterObserver(this);
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            //注销smsContentObserver
            getContentResolver().unregisterContentObserver(smsContentObserver);
        }
    
        /**
         * 注册SmsContentObserver
         * <p>
         * 为什么注册的时候使用的URI是"content://sms/",而直接是"content://sms/inbox"?
         * 通过测试发现只能监听此Uri “content://sms/”
         * 而不能监听其他的Uri,比如"content://sms/inbox"等
         */
        private void registerSmsContentObserver() {
            smsContentObserver = new SMSContentObserver(this, mHandler);
            getContentResolver().registerContentObserver(Uri.parse("content://sms/"), true, smsContentObserver);
        }
    
        /**
         * 检测是否有赋予READ_SMS权限,
         * 若有则注册SmsContentObserver
         * 若没有则提醒用户授权
         *
         * @param context
         */
        private void checkPermissionsAndRegisterObserver(Context context) {
            if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_SMS) != PackageManager.PERMISSION_GRANTED) {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_SMS}, READ_SMS_PERMISSION);
            } else {
                registerSmsContentObserver();
            }
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            switch (requestCode) {
                case READ_SMS_PERMISSION:
                    if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        registerSmsContentObserver();
                    } else {
                        Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();
                    }
                    break;
                default:
                    break;
            }
        }
    }
    
    

    SMSContentObserver .class

    package com.ryan.smscontentobsever;
    
    import android.content.Context;
    import android.database.ContentObserver;
    import android.database.Cursor;
    import android.net.Uri;
    import android.os.Handler;
    import android.util.Log;
    
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import static com.ryan.smscontentobsever.MainActivity.SMS_CODE;
    
    /**
     * 短信验证码截取
     */
    public class SMSContentObserver extends ContentObserver {
    
        private static final String TAG = "SMSContentObserver";
    
        private Context mContext;   //上下文
        private Handler mHandler;   //更新UI线程
        private String code;        //验证码
    
        public SMSContentObserver(Context context, Handler handler) {
            super(handler);
            mContext = context;
            mHandler = handler;
        }
    
        /**
         * 回调函数, 当所监听的Uri发生改变时,就会回调此方法
         * <p>
         * 注意当收到短信的时候会回调两次
         *
         * @param selfChange 此值意义不大 一般情况下该回调值false
         * @param uri
         */
        @Override
        public void onChange(boolean selfChange, Uri uri) {
            super.onChange(selfChange, uri);
            Log.e(TAG, uri.toString());
    
            // 第一次回调 不是我们想要的 直接返回
            if (uri.toString().equals("content://sms/raw")) {
                return;
            }
    
            // 第二次回调 查询收件箱里的内容
            Uri inboxUri = Uri.parse("content://sms/inbox");
    
            // 按时间顺序排序短信数据库
            Cursor c = mContext.getContentResolver().query(inboxUri, null, null,
                    null, "date desc");
    
            if (c != null) {
                if (c.moveToFirst()) {
                    // 获取手机号
                    String address = c.getString(c.getColumnIndex("address"));
                    // 获取短信内容
                    String body = c.getString(c.getColumnIndex("body"));
    
                    Log.e(TAG, "onChange: -----------------------" + address + "---" + body);
    
                    // 判断手机号是否为目标号码
    //                if (!address.equals("你的目标号码"))
    //                {
    //                    return;
    //                }
    
                    // 正则表达式截取短信中的6位验证码
                    //这个地方要特别注意,如果你的验证码不是6位数字,就不会自动填入,需要处理一下
                    Pattern pattern = Pattern.compile("(\\d{6})");
                    Matcher matcher = pattern.matcher(body);
    
                    // 如果找到通过Handler发送给主线程
                    if (matcher.find()) {
                        code = matcher.group(0);
                        mHandler.obtainMessage(SMS_CODE, code).sendToTarget();
                    }
                }
            }
            c.close();
        }
    }
    
    

    activity_main.xml

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:padding="50dp">
    
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="您的验证码为:" />
    
        <EditText
            android:id="@+id/smsCode"
            android:focusable="false"
            android:focusableInTouchMode="false"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
    
    </LinearLayout>
    
       <uses-permission android:name="android.permission.READ_SMS" />
    

    下载地址:https://download.csdn.net/download/qq_31939617/11367198

    展开全文
  • android获取短信验证码自动

    千次阅读 2017-08-20 17:37:08
    android获取短信验证码自动入的简单实现,可以直接用 权限 读取短信权限--> android:name="android.permission.RECEIVE_SMS"/> android:name="android.permission.READ_SMS" /> 布局 activity_...
  • 主要利用了ihtmldocument2获取ie中的验证码图片,再利用tesseract对验证码图片进行识别,利用js将识别结果输入到验证码
  • Android中实现短信验证码自动入 由于目前的好多应用都有短信验证,短信验证码收到后,用户手动输入已经显得有麻烦,于是我写了这篇博文,希望能对大家有所帮助。 实现步骤: 1.写一个SmsBroadcastReceiver,在...
  • 验证码

    2019-05-17 09:38:52
    验证码的样式,把验证码定位到输入验证码的输入框的右边上 Input 标签的 rounded 是设置输入框的四角为圆角 Img 标签 是放验证码 @验证码@ <div class="input-group mb-3"> <div class="input-group-...
  • 在现今许多APP中需要进行一些输入短信验证码的操作,一个比较好的用户体验是应用检测到目标短信后自动提取验证码到相应的控件框中,不需要用户手动输入验证码。 这个功能是如何实现的呢? 根据目前掌握的知识,我做...
  •  就是我在调试的时候,故意验证码,可点注册后竟然没有提示?页面刷新了一下又回来了。。。。    最后才知道,其实是因为我们的html没有配置完,而且这个错误我已经不是第一次犯了。。。。。。。 解决办法: ...
  • 在这里跟大家分享下Android的内容监听者 ContentObserver 内容监听者是监听一个指定路径里面的数据,当发生改变的时候会调用onChange方法,在这里跟大家实现一个验证码的自动填写。 布局代码就一个TextView用来...
  • // 获取短信验证码 let codess = this.$refs.sms.body let codeRegex = /[0-9]{4}/g; if(codess && codess.includes('主要文本内容')) { let magex = codess.match(codeRegex) if...
  • <button type ="button" class="normal-btn switch-btn" id = "SwitchCodefuck" onclick="SwitchCode()">Switch Code</button> 1,button 默认属性为 type=“submit” ;需要将其改为 type=“button”...
  • 自动提取短信验证码填入到编辑框.rar,太多无法一一验证是否可用,程序如果跑不起来需要自调,部分代码功能进行参考学习。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 12,734
精华内容 5,093
关键字:

怎么填验证码