微信扫一扫揭秘

ManieRoland 8年前
   <p>要探索二维码的秘密之前,我们首先需要简单了解下什么是二维码。</p>    <h3><strong>什么是二维码</strong></h3>    <p>二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理。</p>    <p>其实简单的说二维码就是一段简单的字符串图形化的展示,它可能是一个url,一段文字,或者是一首唐诗也不错哦</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/90eb3bc9b5ad7c557e33fd42bc135aef.jpg"> <img src="https://simg.open-open.com/show/c0927cd31c1202b2aacd415f41c3a391.jpg"> <img src="https://simg.open-open.com/show/700cfe8a8fcb7834bbd3f9403348504d.jpg"></p>    <h3><strong>为什么要使用二维码</strong></h3>    <p>二维码的诞生可以说是真正的促进这移动互联网的发展。</p>    <ul>     <li>信息获取(名片、地图、WIFI密码、资料)</li>     <li>网站跳转(跳转到微博、手机网站、网站)</li>     <li>广告推送(用户扫码,直接浏览商家推送的视频、音频广告)</li>     <li>手机电商(用户扫码、手机直接购物下单)</li>     <li>防伪溯源(用户扫码、即可查看生产地;同时后台可以获取最终消费地)</li>     <li>优惠促销(用户扫码,下载电子优惠券,抽奖)</li>     <li>会员管理(用户手机上获取电子会员信息、VIP服务)</li>     <li>手机支付(扫描商品二维码,通过银行或第三方支付提供的手机端通道完成支付)</li>    </ul>    <p>在不同的领域,不同的行业二维码都可以用来简化原来的工作流程,那么我们为什么不来试试二维码呢?</p>    <h3><strong>二维码的生成</strong></h3>    <p>通过对上面的了解相信大家对二维码已经有了一定的了解,那么二维码是怎么生成的呢?</p>    <p>维码一共有40个尺寸。官方叫版本Version。Version 1是21 x 21的矩阵,Version 2是 25 x</p>    <p>25的矩阵,Version 3是29的尺寸,每增加一个version,就会增加4的尺寸,公式是:(V-1) <em> </em></p>    <p>4 + 21(V是版本号) 最高Version</p>    <p>40,(40-1)</p>    <p>4+21 = 177,所以最高是177 x 177 的正方形。</p>    <p>二维码的基本结构如下:</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/dade5a7607c3662dedc512f9f6ed1bfb.jpg"></p>    <p>二维码一般由定位点图案、功能性数据、数据码和纠错码组成,生成的算法是固定的有需要的同学可以了解</p>    <p><a href="/misc/goto?guid=4959715751662807050" rel="nofollow,noindex">二维码的生成原理</a> 、</p>    <p><a href="/misc/goto?guid=4959715751753761982" rel="nofollow,noindex">二维码生成原理解析</a></p>    <p>如今,基本上各个语言都有了比较好的二维码生成与解码的开源项目,有需要的同学可以自行google,本次我们呢不做具体介绍,因为不是重点啊 。</p>    <h2><strong>微信二维码揭秘</strong></h2>    <h3><strong>微信的二维码有哪些</strong></h3>    <p>在平时的使用中我们可以发现微信在很多的场景中都有二维码的使用在,名片,联系人,支付等尤为明显,可以说二维码已经成为微信不可或缺的设计呢功能了。</p>    <p>那么微信的二维码到底有哪些是呢?</p>    <p>以二维码扫描结果和功能区分</p>    <ol>     <li>http(s)://www. <em>*</em> .com http链接</li>     <li>weixin://qr/××× 微信二维码</li>     <li><a href="/misc/goto?guid=4959715751839012937" rel="nofollow,noindex">http://weixin.qq.com/r/×××</a> 微信二维码名片</li>     <li><a href="/misc/goto?guid=4959715751924272428" rel="nofollow,noindex">https://login.weixin.qq.com/l/×××</a> 网页登陆二维码</li>     <li><a href="/misc/goto?guid=4959715752004642259" rel="nofollow,noindex">https://login.wechatapp.com/l/×××</a> 国际部网页登陆二维码</li>     <li>weixin://wxpay/bizpayurl/××× 微信支付</li>     <li><a href="/misc/goto?guid=4959715752082035566" rel="nofollow,noindex">http://weixin.qq.com/g/×××</a> 微信群二维码</li>    </ol>    <p>其实在上面的二维码例子中大体上可以分为两类,1,4,5未一类,其他的为一类。第一类主要是普通类型和涉及登录相关的逻辑,第二类中的逻辑就是我们本次要谈论的逻辑。</p>    <p>第二类流程如下:</p>    <p><img src="https://simg.open-open.com/show/3427894d5181141d923f638c95742895.jpg"></p>    <h3><strong>实现微信二维码逻辑</strong></h3>    <p>由上面的介绍我们很清楚的知道,我们想要实现上面的功能我们生成的二维码肯定是一个url,然后对本本地是否安装有app的判断也是在服务端实现的(其实就是个js而已,不要怕),当然在客户端也需要对自己的代码做相应的配置。</p>    <p>客户端配置</p>    <p>由于本人系Android开发工程师,对ios的了解也不是太多,所以本次配置主要是对android端而言的。</p>    <p>首先在manifest文件中配置扫描后需要跳转activity的intent-filter</p>    <p>还需要制定对应的host、pathPrefix、scheme</p>    <p>至于host、pathPrefix、scheme是什么,大家可以自己去google下,其实只要了解Url的组成原理就ok了。</p>    <pre>  <code class="language-java"><activity android:name=".otherTest.scan.FromUrlActicity">          <intent-filter>              <action android:name="android.intent.action.VIEW" />              <category android:name="android.intent.category.BROWSABLE" />              <category android:name="android.intent.category.DEFAULT" />              <data                  android:host="www"                  android:pathPrefix="/com/test"                  android:scheme="flyou" />          </intent-filter>      </activity></code></pre>    <p>上面的host和 pathPrefix是可以省略的,不过还是推荐大家都写上。</p>    <p>这样客户端的配置就完成了。</p>    <p>服务端解析</p>    <p>首先根据浏览器的userAgent判断来自哪个终端,如果是PC则直接跳转到下载页,如果是Android或者Ios则判断本地判断本地app书否存在如果存在则根据定义的scheme打开相应页面并传递数据,如果不存在该app则跳转到下载页面。</p>    <pre>  <code class="language-java"><!DOCTYPE html>  <html>  <head>  <meta charset="utf-8" />  <title>我是一个测试页面</title>  <meta name="viewport" content="width=320.1, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no">  <meta content="telephone=no" name="format-detection" />  <meta name="apple-mobile-web-app-capable" content="yes" />    <script>  /*获取自定义数据*/  function getQueryString(name) {        var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");        var r = window.location.search.substr(1).match(reg);        if (r != null) return unescape(r[2]);        return null;    }    var userId=getQueryString("userId");  var u = navigator.userAgent || '';   /*首先判断是否是pc,若是pc访问则跳转到http://flyou.ren/ */  var isPC = !/(iphone|ios|android|mini|mobile|mobi|Nokia|Symbian|iPod|iPad|Windows\s+Phone|MQQBrowser|wp7|wp8|UCBrowser7|UCWEB|360\s+Aphone\s+Browser)/i.test(u);  var isAndroid = u.indexOf('Android') > -1 || u.indexOf('Linux') > -1; //android终端或者uc浏览器  var isiOS = !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/); //ios终端  if (isPC) { location.href = "http://flyou.ren/"; }  else if (isAndroid) {      var the_href="http://flyou.ren/2016/09/13/%E5%BE%AE%E4%BF%A1%E6%89%AB%E4%B8%80%E6%89%AB%E6%8F%AD%E7%A7%98";//获得下载链接或在app下载页      location.href="flyou://www/com/test?userId="+userId;//打开某手机上的某个app应用,并传递参数      setTimeout(function(){          window.location=the_href;//如果超时就跳转到app下载页,或者直接下载      },2000);  }  else{      //服务端可以根据ios 先关逻辑做相应的判断      alert('宝宝暂时还不持支持IOS操作系统,宝宝会努力的')  }    </script>      </head>    </html></code></pre>    <p>服务端返回数据处理</p>    <p>在对应的Acticity里处理传递回来的参数,并做相应的处理,如微信名片二维码的功能,返回给相应页面用户id,当然这个用户的userId可以是经过加密的(别我问我怎么加密,你们这么加密我也不想知道)。</p>    <pre>  <code class="language-java">public class FromUrlActicity extends AppCompatActivity {    private TextView tvUserid;    @Override  protected void onCreate(Bundle savedInstanceState) {      super.onCreate(savedInstanceState);      setContentView(R.layout.activity_qrcode_acticity);      tvUserid = (TextView) findViewById(R.id.userid);      Uri uriData = this.getIntent().getData();      String userId = uriData.getQueryParameter("userId");        tvUserid.setText("我是来自服务器的UserId:"+userId);        }  }</code></pre>    <p>扫描二维码</p>    <p>自己活着使用第三方工具生成二维码如下</p>    <p style="text-align:center"><img src="https://simg.open-open.com/show/35cb831368a9e2f47e02e3130db8dca8.jpg"></p>    <p>二维码对应字符串:http:\henu.flyou.ren/scan?userId=553274238</p>    <p>在手机上使用浏览器扫一扫扫描二维码即可进入如下界面,并获得服务端传来的参数,完成相应的逻辑</p>    <p><img src="https://simg.open-open.com/show/129550c4fc45239d6796fb0b53dfa651.jpg"></p>    <p>当然,二维码可以向服务器传递多个数据,服务器也可以向客户端返回多个数据,分别定义获取即可。明白了上述的流程想要实现微信的上述流程也是很容易的。</p>    <h2><strong>后记</strong></h2>    <p>当然,二维码的功能并不仅仅局限于上面的逻辑,二维码可以应用在多个行业和领域,那么快快发动你的才智来发现新的大陆吧。</p>    <p> </p>    <p>来自:http://flyou.ren/2016/09/13/微信扫一扫揭秘/</p>    <p> </p>