微信扫一扫揭秘
2016-09-18 13:22 阅读(260)

前言

要探索二维码的秘密之前,我们首先需要简单了解下什么是二维码。

什么是二维码

二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理。

其实简单的说二维码就是一段简单的字符串图形化的展示,它可能是一个url,一段文字,或者是一首唐诗也不错哦

二维码1


二维码2


二维码3


为什么要使用二维码

二维码的诞生可以说是真正的促进这移动互联网的发展。

在不同的领域,不同的行业二维码都可以用来简化原来的工作流程,那么我们为什么不来试试二维码呢?

二维码的生成

通过对上面的了解相信大家对二维码已经有了一定的了解,那么二维码是怎么生成的呢?

维码一共有40个尺寸。官方叫版本Version。Version 1是21 x 21的矩阵,Version 2是 25 x
25的矩阵,Version 3是29的尺寸,每增加一个version,就会增加4的尺寸,公式是:(V-1)4 + 21(V是版本号) 最高Version
40,(40-1)
4+21 = 177,所以最高是177 x 177 的正方形。

二维码的基本结构如下:



二维码一般由定位点图案、功能性数据、数据码和纠错码组成,生成的算法是固定的有需要的同学可以了解
二维码的生成原理
二维码生成原理解析
如今,基本上各个语言都有了比较好的二维码生成与解码的开源项目,有需要的同学可以自行google,本次我们呢不做具体介绍,因为不是重点啊 。

微信二维码揭秘

微信的二维码有哪些

在平时的使用中我们可以发现微信在很多的场景中都有二维码的使用在,名片,联系人,支付等尤为明显,可以说二维码已经成为微信不可或缺的设计呢功能了。
那么微信的二维码到底有哪些是呢?

以二维码扫描结果和功能区分

  1. http(s)://www.*.com http链接

  2. weixin://qr/××× 微信二维码

  3. http://weixin.qq.com/r/××× 微信二维码名片

  4. https://login.weixin.qq.com/l/××× 网页登陆二维码

  5. https://login.wechatapp.com/l/××× 国际部网页登陆二维码

  6. weixin://wxpay/bizpayurl/××× 微信支付

  7. http://weixin.qq.com/g/××× 微信群二维码

其实在上面的二维码例子中大体上可以分为两类,1,4,5未一类,其他的为一类。第一类主要是普通类型和涉及登录相关的逻辑,第二类中的逻辑就是我们本次要谈论的逻辑。

第二类流程如下:

流程图


实现微信二维码逻辑

由上面的介绍我们很清楚的知道,我们想要实现上面的功能我们生成的二维码肯定是一个url,然后对本本地是否安装有app的判断也是在服务端实现的(其实就是个js而已,不要怕),当然在客户端也需要对自己的代码做相应的配置。

客户端配置

由于本人系Android开发工程师,对ios的了解也不是太多,所以本次配置主要是对android端而言的。
首先在manifest文件中配置扫描后需要跳转activity的intent-filter

还需要制定对应的host、pathPrefix、scheme
至于host、pathPrefix、scheme是什么,大家可以自己去google下,其实只要了解Url的组成原理就ok了。

<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>

上面的host和 pathPrefix是可以省略的,不过还是推荐大家都写上。
这样客户端的配置就完成了。

服务端解析

首先根据浏览器的userAgent判断来自哪个终端,如果是PC则直接跳转到下载页,如果是Android或者Ios则判断本地判断本地app书否存在如果存在则根据定义的scheme打开相应页面并传递数据,如果不存在该app则跳转到下载页面。

<!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>

服务端返回数据处理

在对应的Acticity里处理传递回来的参数,并做相应的处理,如微信名片二维码的功能,返回给相应页面用户id,当然这个用户的userId可以是经过加密的(别我问我怎么加密,你们这么加密我也不想知道)。

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);

    }
}

扫描二维码

自己活着使用第三方工具生成二维码如下



二维码对应字符串:http:\henu.flyou.ren/scan?userId=553274238

在手机上使用浏览器扫一扫扫描二维码即可进入如下界面,并获得服务端传来的参数,完成相应的逻辑


当然,二维码可以向服务器传递多个数据,服务器也可以向客户端返回多个数据,分别定义获取即可。明白了上述的流程想要实现微信的上述流程也是很容易的。

后记

当然,二维码的功能并不仅仅局限于上面的逻辑,二维码可以应用在多个行业和领域,那么快快发动你的才智来发现新的大陆吧。



作者: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/