精华内容
下载资源
问答
  • 二维码支付”安全么? 1 引言 随时支付宝和微信的线下不断推广,目前使用手机进行二维码支付已经逐渐成为一种时尚了。 但是大家有没有思考过:这种便捷的支付方式到底安不安全呢?今天我们就针对这个话题来...

    “二维码支付”安全么?

    1   引言

    随时支付宝和微信的线下不断推广,目前使用手机进行二维码支付已经逐渐成为一种时尚了。

    但是大家有没有思考过:这种便捷的支付方式到底安不安全呢?今天我们就针对这个话题来进行一些探讨吧。

    2   二维码简介

    先来简单说说二维码:二维码是用一定规则排布的点阵的图像来编码信息的方式。与二维码对应的是传统的“条码”(一维码)。

    和“条码”一样,二维码具有如下特点:

    1. 容易生成
    2. 容易被机器识别

    但是“二维码”具有更多的优点:

    1. 高容错性
    2. 搞污损能力
    3. 高密度的信息承载能力

    二维码曾被腾讯公司总裁 马化腾 誉为:连接线上和线下的通道。

    随着支付宝,微信,微博等厂商的大力支持和推广,二维码的应用已经逐渐成为生活中随处可见的应用图案了。

    当然,大家最熟悉的使用场景肯定是:移动支付。也是本期重点讨论的领域。

    3   支付场景

    • 身份二维码
    • 收款二维码
    • 付款二维码

    大家可以使用第三方应用扫描微信或者支付宝提供的二维码,可以获取其中代表的含义。比如:两种应用互扫二维码。

    3.1   身份二维码

    微信 身份二维码:

    http://weixin.qq.com/r/L-rg_G-EbIITrZub0097

    支付宝 身份二维码:

    https://qr.alipay.com/apa2uu7j3tpjyxlr00

    不难看出,身份二维码实际上有用的信息就是指定的URL后面的一个串号。这个串号具有如下特点:

    1. 一直固定不变
    2. 无法通过此串号获取用户信息
    3. 仅能被自己的app识别其深层含义(自家app查询自家数据库),客户app扫码后,将弹出相应的显示详细身份或者加好友的界面

    这样很好地兼顾了 隐私性 和 开放性 。

    3.2   收款二维码

    使用UC来扫微信和支付宝的收款二维码。

    微信:

    https://wx.tenpay.com/f2f?t=AQAAAEBfhXKNRIQUrs6fy4XO8p879

    支付宝:

    https://d.alipay.com/i/index.htm?b=RECEIVE_AC&u=mGnPJ/rNBfKKKKKDcQlNGn1mthWAVDa7vw00ow5sM4o=

    明显看出,换了一个API,同时后面带上一串和用户账号无关串号。此串号具有如下特点:

    1. 一直固定不变
    2. 无法通过此串号获取用户信息
    3. 仅能被自己的app识别其深层含义(自家app查询自家数据库),被客户app扫描后,客户app直接调出向对方账号付款的界面

    3.3   付款二维码

    在付款二维码上,微信 和 支付宝 是差不多的,都是一串每分钟就会变一次的一串数字:

    284308793673642130

    此二维码信息具有如下特点:

    1. 是一串不带API的纯数字串
    2. 每分钟变一次
    3. 通过指定的SDK以此数字为参数进行接口调用可以完成扣款

    其实上本质上就是一个付款账号。然后扫码时自动输入这个串号,通过第三方客户端调用支付平台SDK即可以完成扣款。

    此扣款场景及规则如下:支付平台默认只要用户主动出具了二维码,就表明进行了授权扣款,这有点类似于在校园卡在食堂的作用一样,小额交易免除了繁琐的授权流程了。

    关于付款二维码和之前的二维码的区别如下:

    1. 永久不变 和 每分钟必变
    2. API+参数 和 纯参数

    关于第一点的解释,笔者在此插播一个现实生活中的小故事:

    在某早餐店, 笔者问店主:为何不做个二维码放墙上? 店主说:那玩意经常变,我们就不知道怎么弄了。 笔者笑:你说的是付款二维码,那东西如果不变,传播出去后,你的钱会被人随便扣,但是你的收款二维码,你是不是还会担心别人随便给你转钱呢? 店主立刻明白了,笑:当然不会,别人不断给我汇款,我高兴都还来不及呢。

    所以,用户只是担心自己的钱可能被不知情的情况下被划走,但是肯定是不会担心别人给自己汇款的,这就很好的解释了 “不变” 和 “变” 的区别了。

    关于第二点的解释:

    1. app上的扫码所对应的场景众多,必须要做一定的区分,所以带上API名称
    2. 条码枪对应的场景单一,仅仅只是扣款,所以二维码只需要对参数进行编码即可

    4   本节小结

    通过本文的实验和介绍,大家应该对自己手机中的支付app的二维码是怎么回事有大致的了解了吧,后面一节将从安全性上对它们进行分析,敬请期待。。。

    5   概述

    前面的章节我们讲了支付宝和微信的二维码的主要信息载体,本部分则开始讨论其安全风险问题。

    6   安全风险

    关于二维码的风险问题主要从如下几个方面来说:

    1. 隐私问题

      是否出现用户的私有信息随着二维码的传播而被泄露,给用户千万困扰的问题

    2. 越权问题

      是否出现违反用户意途的越权操作问题

    7   隐私问题

    在前面对二维码承载的信息的分析如此可以看出,用户私有的一些信息:

    1. 真实姓名
    2. 账号明文
    3. 手机号码

    都并没有体现在相应的参数当中,黑客很难根据那一串无意义的数据获悉二维码背后的真实的用户信息。当然,除非黑客攻陷了微信或者支付宝的数据库了,这基本上不太可能。通过这些串号获取到的用户昵称和头像也仅仅限制在当前app中。

    8   越权问题

    身份二维码。这个因为单方面加了好友后,是需要二维码身份主人进行验证,所以不存在越权问题。

    收款二维码。正如上一文中提到的,如果有人未经当事人同意“越权”给当事人转账,你会有意见么?

    付款二维码。有过在超市支付宝付款经历的人肯定知道,掏出手机,亮出二维码,收银员条码枪一过,一秒过后,钱就被扣走了。如果要说有直接的金钱损失,可能就是这个地方了吧。下面我们来细说此场景。

    9   越权扣款

    在前面的文章中提到,付款二维码具有如下特点:

    1. 一分钟强制变一次
    2. 能且只能被使用一次

    设想这样的场景:

    超市里面,收银员A在零售系统中核算出商品价格,顾客B亮出付款二维码,A拿起条码枪扫码,完成扣款,钱从B的账号进入到A所属的公司中。

    那么这里面是否存在 越权扣款 的漏洞?

    我的回答是:有,但是这需要我们大开脑洞才能想到。

    由于二维码是一种通过光线视觉来传递信息的方式,而且二维码出示的时候,并不会指定要扣款给谁,所以在顾客B出示二维码到被收银员A扫码之间的空档里面,可能会被别人截获。

    当然,我们现在都不考虑一些网络通路被攻破,数据通讯被劫持和篡改的情况,就按照正常的流程来走。顾客B出示了二维码,然后由C通过设备直接提前识别了二维码,并完成了扣款。

    这个C有如下可能:

    1. 隐藏在旁边某人衣帽里面的针孔摄像头
    2. 附近大厅上方的某个已经“叛变”的监控摄像头
    3. 旁边某个玩手机的路人甲乙丙丁
    4. 带着眼镜的斯文四眼仔

    他们的共同特点就是:

    1. 快速识别二维码。通过光学识别设备(即摄像头)即可。
    2. 拥有扣款的资格,黑客有各种办法使用冒牌身分获取到此资格。
    3. 能快速完成识别和扣款。目前的机器视觉和后续的自动化扣款程序可以实现。

    假如我们这个脑洞成真了,那么就是这样的场景了:

    1. 顾客B掏出手机展示付款码
    2. 在收营员A扫码前B已经被扣款
    3. 环顾周边的购物的人山人海,并没发现可疑的人
    4. 找相关机构报案,数额太少,浪费自己的时间不划算
    5. 如果自己时间不值钱,坚持报案,数额不少,不予以立案
    6. 顾客B不相信社会了,再也不用这种付款方式了

    10   小结

    本节的脑洞开得有点大了。但是到底是不是耸人听闻了,还真不一定。虽然这两家公司的开发人员和产品人员也并不是吃白饭的,但是黑客和黑产从业人员也更不是吃白饭的。

    11   概述-3

    在上一章节里面,我们提到过,其实支付厂商和技术人员和黑产从业人员技术孰高孰低,还真不好说。但是我们目前还是尽力相信暂时正方是占据上风的吧,那么支付服务厂商到底做了哪些措施来保证这个安全呢?我们可以来分析一下。当然,本文的定位还是给技术小白的简谱吧,技术大牛面前还是属于献丑了。

    12   风险控制

    虽然确实存在以上漏洞,但是其实细心的用户可能注意到了,微信和支付宝尽力地做了相应的措施:

    1. 对申请扣款资格主体身份进行严格审核,虽然说不能百分百,但是还是可以极大增加假冒门槛。当然厉害的黑客还是有办法过。
    2. 设立资金保险。当然,估计并没有多少人去投保了。
    3. 限额。将这种扣款方式进行限定,将其局限在小额场景。但是每次被扣除个几百块,也还是有点心疼的吧。

    直接出示付款码,让对方扫码扣款,这种方式确实是自己目前体会到的最便捷的支付方式了。但是这种方式存也确实存在一定的安全风险,所以用户在使用时,请养成良好的习惯,让二维码暴露在公众视野下的时间尽量短,看到的人尽量少。否则,稍微的疏忽就成了黑客们线下薅羊毛发家致富的场景了。

    13   方案建议

    关于此“安全漏洞”,在技术流程上的解决方案是:

    在扫码之后,加入“用户确认”环节, 要求用户在自己的app上做一个简单的交互,表示自己 知晓 并 认可 当前的扣款行为。

    当然,这个“简单” 最后加一道确认环节,关于这个环节,我们可以头脑风暴一下,我先说下自己的“脑洞”:

    1. 加一个类似苹果开机的滑动解锁确认
    2. 指纹确认(对于有指纹模块的手机来说不错)
    3. 做一个按钮图标,需要用户长按2s确认
    4. 要求用户摇一摇把钱甩出去(扫码后,做个图片:钱一半在口袋外面了)
    5. 要求用户对着手机吹一口气把钱吹出去(吹气后,加个钱被吹走的动画)

    大家有看到这几个构想的,如果觉得比较好,请转达给微信或者支付宝的产品经理,如果被采用了,请给我发个红包哦(手动龇牙表情)。

    14   结论

    虽然本文有点脑洞大开,只是希望大家能明白:我们享受到了新型的便捷的付款方式的同时,其实是牺牲了一定的安全性的。在商场使用刷卡支付,刷卡后输入密码,虽然麻烦,但是却有一个重要的“用户确认环节”,还是能避免掉意外扣款。当然这也是产品的权衡了,看这个风险出现的概率是否值得提供商牺牲掉好的付款体验了。

    现在还没有出现那种被机器视觉薅羊毛的扣款事件吧,也不知道今后会不会有,希望是我杞人忧天了吧。

    转自:https://www.cnblogs.com/beer/p/6918180.html

    展开全文
  • 聚合支付二维码生成原理

    千次阅读 2020-06-08 22:38:03
    聚合支付二维码生成原理 聚合支付平台提供平台支付URL,生成统一的支付二维码。当消费者根据二维码扫描时,聚合支付平台根据扫描者浏览器类型判断支付类型,并提交参数给聚合支付平台支付处理接口处理。平台支付处理...

    聚合支付二维码生成原理

    聚合支付平台提供平台支付URL,生成统一的支付二维码。当消费者根据二维码扫描时,聚合支付平台根据扫描者浏览器类型判断支付类型,并提交参数给聚合支付平台支付处理接口处理。平台支付处理接口根据支付类型和商户ID,调用相应的支付渠道支付接口进行支付处理

    在这里插入图片描述

    1.商户分别开通微信、支付宝、京东金融等支付渠道,各个平台审核通过后会生成微信商户编码,支付宝商户编码和京东金融商户编码
    2.商户将这些渠道的支付账号配置到聚合平台中,并分配给用户一个聚合唯一用户标识ID
    3.聚合平台通过微信、支付宝和京东金融第三方API调用形成具体支付过程(这个过程商户不用关注),当其他消费者扫描带有用户标识的聚合平台URL时,根据扫描者手机使用的内置UAG判断是哪个支付平台,前端获取到后把商户标识和支付方式传递给聚合支付平台的支付API,
    4.聚合平台的支付API根据参数生成相应的平台支付订单
    5.消费者确认支付完成
    6.商户定期在聚合支付后台提现金额到对应账号即可。

    简单的 demo

    扫描二维码本质上就是通过扫描得到一个网址,所以,我们要写一个页面。
    支付宝的链接可以通过 js 直接跳转;微信的不能直接跳转到支付,只能通过微信的扫描接口唤起支付模块,所以变通一下,让微信的链接变成微信的支付二维码,再扫描一次。

    其实,像美团的二维码是可以直接跳转到微信的支付模块的,并不用扫描第二次,笔者尝试了很多方法仍然不能直接跳转,推测是美团和微信有相关协议让他们可以直接跳转,如果有了解的读者能赐教一二将不胜感激。

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0;" />
        <title>jasonPayTestDemo</title>
    </head>
    <body>
    
    <!-- 隐藏微信支付的二维码,可以是个的也可以是企业的,如果做统一聚合一般都是做企业的,支付成功到企业账户后再转给个人用户或者个人用户使用提现再转到其个人微信或者其他账户中去 -->
    <div class="container" id="wechat" style="display: none;">
       <div style="text-align: center;">
           <img src="http://qr.liantu.com/api.php?text=wxp://f2f0lGxS0y-AT4xJ9IIXI_nKcp3U2b2b_W0L">
           <h3>please use wechat, long presh and pay</h3>
       </div>
    </div>
    </body>
    </html>
    <script language="javascript">
    
        var ua = navigator.userAgent.toLowerCase();
        if(ua.match(/MicroMessenger/i)=="micromessenger") {
            goAndPayByWechat();
        } else if(ua.match(/AlipayClient/i)=="alipayclient"){
            goAndPayByAli();
        } else{
            alert("please use wechat or alipay");
        }
    
        function goAndPayByAli(){
             window.location.href="HTTPS://QR.ALIPAY.COM/FKX09508CLUZB0JA2UHC36";
        }
    
        function goAndPayByWechat(){
            document.getElementById("wechat").removeAttribute("style");
        }
    </script>
    

    参考资料

    作者:Jason_M_Ho
    链接:https://www.jianshu.com/p/ec23449820ba

    展开全文
  • 二维码支付码的工作原理那点事

    千次阅读 2020-01-03 16:08:45
    二维码支付这些年发展的如火如荼,前两年在另外一个站上也大致分析过二维码支付原理,年底摸摸鱼,重新整理一下吧。 (说实话我很讨厌有的人借着学习的名义把博客上的文章抄来抄去) 1、数字支付码 数字支付码...

    二维码支付这些年发展的如火如荼,前两年在另外一个站上也大致分析过二维码支付的原理,年底摸摸鱼,重新整理一下吧。

    (说实话我很讨厌有的人借着学习的名义把博客上的文章抄来抄去)

    1、数字支付码

    数字支付码就是打开微信和支付宝付款界面的那串玩意,通过数字找到对应账户,再从账户里扣钱,就这么一回事。

    看起来很简单,实际上这里面的过程就非常复杂了。

    大致上要解决的问题有这么几个:

    a.随机性

    b.识别性

    c.可用性

    d.安全性

    首先,随机性就意味着生成的结果必须是离散的,如果按照序列变化,很容易就会被穷举出来;

    其次,识别性就要求通过一串数字能很快的找到对应的账户,这就要求对数据的处理时间不能太长太多;

    然后,可用性是说在网络不好的情况下,要允许客户端生成离线序列,不影响支付的可用性;

    最后,安全性不说都知道了,要保证一码一账户,不能随便被人随时随地造一个有效的出来;

    目前网络上讨论的不外乎两种方案:

    第一种,直接生成支付码下发给客户端,完整存储数字序列。但是这依赖着服务端,如果有效期过长会有安全问题,如果有效期太短,又会对数据处理有压力,更可怕的是用户数量上去了,这个量就是一个天文数字。

    第二种,基于时间的TOTP算法,但是纯粹这种算法是不能直接识别账户来源的,也就意味着要把所有用户的密钥全部计算一遍才可能知道是谁的,这个数据量,估计算到一半前面的就都过期了。

    其实以上的思路都是对的,如果结合在一起就基本上就是实现方案了。

    大致上就目前市面上的付款码而言,前1-2位是用于标识这是什么机构的标识头,这是为了方便聚合支付厂商定的,也可以过滤掉非本系统的支付码,例如微信是1开头的,支付宝是2开头的,银联的云闪付是62开头的,这就有些跑马圈地的意思了。未来可以预期的是国家会对这个出国标,不然地圈完了,别人就没法玩了,参考卡bin之类的。

    除了标识头以外,接下来的部分大概会分成前半部的【token】或者称之为【随机数】的【挑战码】,而后面一部分几位是类似于【应答值】。这里我们先把随机性的问题解决掉了。

    那么如何从几个数字的条码里识别用户?这才是条码支付的核心。

    这样就必须提前把身份信息注册到条码里,也就是说客户端在联机的时候,预先向服务器里申请 token,这样某一个 token 被谁申请了,服务器自然就记录了。到这里可识别性就解决了。

    当然这还不足,如何鉴权,那就必须在服务器上和客户端里进行相同的操作,取出付款码里的【应答值】和上面token用户的密钥做允许误差范围时间内的计算,如果有符合的结果,即鉴权成功。至于算法是 TOTP 还是HMAC,这个随便了我们并不需要关心。这样即便被人获得token,没有相应的密钥也无法得到正确的【应答值】。这样安全问题和离线可用性的问题我们都也一起解决了。进一步的说,后续还可以通过调整token的可尝试挑战次数、token用后即废等等方式来提高安全性。

    接着,我们可能还得预留几位做自己的用途,例如,我选择了哪张卡来支付,我们可以预留一位0-9来标识选的那张卡,但是一位的话意味着只能绑10张卡,那么两位的话又浪费了,要知道条码支付是寸土寸金的,数字长度越长,条码越挤,可识别度就越低(难),手机屏幕就那么大,所以并不是越长越好,将来大家可不想横着展示条码给别人吧!

    最后,十来二十位的条码肯定是不足的,要么扩大付款码长度,要么 token多用户共享,也就是一个 token 是可能被多个用户一起注册的,但是我们可以从 token 里知道有哪些用户在用,然后通过检索每个用户的【应答值】就可以完成鉴权动作了。所以这里就存在一个风险,一个 token 最大同时共享给多少人可以控制在可接受的风险范围?这些就是风险部门去处理的数学问题啦。

    2、离线支付码

    这个其实就是和公交卡一样的原理,大家有共同的密钥或者基于 PKI 的鉴权,生成账户支付码(无外乎就是金额、账号之类的,再加一个有效期),设备检查通过就可以了。反正要预先充钱,或者离线计费,感觉没什么可说的。

     

    以上,以后想到什么点子了再加上来。

    展开全文
  • 支付宝扫描二维码原理是什么,用扫描软件扫描支付宝二维码得到的是一串网址,怎样把这个网址用支付宝打开来实现支付
  • 二维码生成原理及解析代码

    万次阅读 多人点赞 2017-12-18 22:35:06
    二维码生成原理及解析代码 自从大街小巷的小商小贩都开始布满了腾讯爸爸和阿里爸爸的二维码之后,我才感觉到我大天朝共享支付的优越性。最近毕业论文写的差不多了,在入职之前多学一些东西也是好的。这里秉着好奇心...

    二维码生成原理及解析代码

    自从大街小巷的小商小贩都开始布满了腾讯爸爸和阿里爸爸的二维码之后,我才感觉到我大天朝共享支付的优越性。最近毕业论文写的差不多了,在入职之前多学一些东西也是好的。这里秉着好奇心,研究一下二维码的生成,并尝试性写一个二维码解析源码。

    注:暂时只有二维码原理,笔者这段时间会持续研究解析代码,并随进度持续更新。

    参考网址:
    《二维码的生成细节和原理》
    《QR Code Tutorial》
    《Hello World!》—— 知乎专栏文章
    《为程序员写的Reed-Solomon码解释》

    一. 二维码基本知识

    二维码另一个名称是QR Code(Quick Response Code),近年来在移动设备上经常使用,与传统条形码相比,可以存储更多的信息。二维码本质上是个密码算法,基本知识总结如下。
    首先,二维码存在 40 种尺寸,在官方文档中,尺寸又被命名为 Version。尺寸与 Version 存在线性关系:Version 1 是 21×21 的矩阵,Version 2 是 25×25 的矩阵,每增加一个 Version,尺寸都会增加 4,故尺寸 Size 与 Version 的线性关系为:

    Size=(Version1)×4

    Version 的最大值是 40,故尺寸最大值是(40-1)*4+21 = 177,即 177 x 177 的矩阵。

    二维码结构如下图 1.1 所示:


    SouthEast
    图1.1 二维码结构

    二维码的各部分都有自己的作用,基本上可被分为定位、功能数据、数据内容三部分。

    • 定位图案:
      • Position Detection Pattern, 定位图案:用于标记二维码矩形的大小;用三个定位图案即可标识并确定一个二维码矩形的位置和方向了;
      • Separators for Position Detection Patterns, 定位图案分割器:用白边框将定位图案与其他区域区分;
      • Timing Patterns, 时序图案:用于定位,二维码如果尺寸过大,扫描时容易畸变,时序图案的作用就是防止扫描时畸变的产生;
      • Alignment Patterns, 对齐图案:只有在 Version 2 及其以上才会需要;
    • 功能数据:
      • Format Information, 格式信息:存在于所有尺寸中,存放格式化数据;
      • Version Information, 版本信息:用于 Version 7 以上,需要预留两块 3×6 的区域存放部分版本信息;
    • 数据内容:剩余部分存储数据内容
      • Data Code, 数据码;
      • Error Correction Code, 纠错码;

    二. 数据编码

    2.1 数据编码信息

    二维码的数据编码信息如下图 2.1, 2.2 中的列表所示:


    SouthEast
    图2.1 模式编号指示器


    SouthEast
    图2.2 字符计数指示器中的位数

    上图 2.1 中,展示的是二维码支持的数据编码模式。
    :其中中文编码模式为 1101;

    上图 2.2 中展示了不同版本(即不同尺寸)的二维码,单个编码对应二进制的位数。
    :二维码规格说明书中,存在各式各样的编码规范表;

    图2.1, 2.2 表格具体含义,在后面的例程中会具体讲解。

    2.2 数据编码形式

    2.2.1 数字编码(Numeric Mode)

    数字编码的范围为 0~9。
    对于数字编码,统计需要编码数字的个数是否为 3 的倍数:如果不是 3 的倍数,则剩下的 1 位或 2 位会被转为 4bits 或 8bits(十进制转二进制),每三位数字都会被编成 10bits, 12bits, 14bits,具体编码长度仍然需要二维码尺寸决定。

    2.2.2 字符编码(Alphanumeric Mode)

    字符编码的范围有:

    • 数字 0~9;
    • 大写 A~Z(无小写);
    • 几个符号$ % * + - . / 和空格。

    上述字符映射为一个索引表,如下图 2.3 所示:


    SouthEast
    图2.3 字符映射索引表

    图中 Char 表示字符,Value 表示字符对应的索引值。
    索引表中共 45 种对应关系,字符编码的过程,就是将每两个字符分为一组,然后转成上图 2.3 的 45 进制,再转为 11bits 的二进制结果。对于落单的一个字符,则转为 6bits 的二进制结果。
    此外,根据上图 2.2 的设定,对不同 Version 的二维码使用 9/11/13 个二进制表示。

    注:
    上图 2.3 中的 SP 代表空格。

    2.2.3 字节编码(Byte Mode)

    可以是 0-255 的 ISO-8859-1 字符。有些二维码的扫描器可以自动检测是否是 UTF-8 的编码。

    2.2.4 日文编码(Kanji Mode)

    日文编码同时也是双字节编码,同样也可以用于中文编码。
    日文与中文编码流程基本相似:

    1. 首先减去一个值;
    2. 挑出差值结果的前两个 16 进制,乘以 0xC0;
    3. 加上后两个 16 进制位;
    4. 转为 13bits 编码;

    按照日文编码集 SHIFT_JIS为参照,可查询日文字符的对应编码。以“雅”与“芒”为例,转换过程如下图 2.4 所示:


    SouthEast
    图2.4 日文编码流程展示

    2.2.5 其他编码

    其他类型的编码本文中不详细说明。其中包括:

    • 特殊字符集(Extended Channel Interpretation Mode):主要用于特殊的字符集,并不是所有的扫描器都支持这种编码;
    • 混合编码(Structured Append Mode):说明该二维码中包含了多种编码格式;
    • 特殊行业编码(FNC1 Mode):主要是给一些特殊的工业或行业用的,如GS1条形码等;

    2.3 数据编码示例说明

    分别用一个数字编码与字符编码的示例,说明数据编码的过程:

    2.3.1 例程1:数字编码

    问题:对于 Version 1 尺寸的二维码,纠错级别为 H,编码为:01234567
    解析步骤:

    1. 将上述数字分为三组:012, 345, 67;
    2. 查询图 2.2 表格内容,Version 1 二维码的数字编码应转换为 10bits 的二进制数字,故将上面三组数字转为二进制分别为:012→0000001100, 345→0101011001, 67→1000011;
    3. 将三个二进制串连接起来:0000001100 0101011001 1000011;
    4. 将数字的个数转成二进制:对于数字编码,数字长度依旧用图 2.2 表格中查到的 10bits 二进制数字来表示,数字共有 8 个,故数字个数的二进制形式为:8→0000001000;
    5. 查询图 2.1 表格内容,数字编码的标志为 0001,将编码标志与步骤 4 编码结果加到步骤 3 结果之前,故最终结果为:0001 0000001000 0000001100 0101011001 1000011

    2.3.2 例程2:字符编码

    问题:对于 Version 1 尺寸的二维码,纠错级别为 H,编码为:AE-86
    解析步骤:

    1. 在图 2.3 的字符索引表中分别找到 AE-86 五个字符的索引分别为:(10, 14, 41, 8, 6);
    2. 将五个字符两两分组:(10, 14) (41, 8) (6);
    3. 字符编码应将字符组转换为 11bits 的二进制,故上述三组字符首先转为 45 进制后再转为二进制:
      • (10, 14):转为 45 进制:10×45+14=464;再转为 11bits 的二进制:00111010000;
      • (41, 8):转为 45 进制:41×45+8=1853;再转为 11bits 的二进制:11100111101;
      • (6):转为 45 进制:6;再转为 6bits 的二进制:000110;
    4. 将步骤 3 中得到的三个二进制结果连接起来:00111010000 11100111101 000110;
    5. 查询图 2.2 表格内容,Version 1 二维码的字符个数应转换为 9bits 的二进制数字,对于 5 个字符,二维码字符个数转为 9bits 二进制为:000000101;
    6. 查询图 2.1 表格内容,字符编码的标志为 0010,将编码标志与步骤 5 编码结果加到步骤 4 结果之前,故最终编码结果为:0010 000000101 00111010000 11100111101 000110;

    三. 结束符与补齐符

    对于结束符和补齐符,我们直接举例进行说明。
    问题:对于 Version 1 尺寸的二维码,纠错级别为 H,以笔者的英文名作为编码:CHANDLERGENG
    按照 2.3.2 字符编码例程进行分析,得到编码如下:

    编码 字符数 CHANDLERGENG 的编码
    0010 000001101 01000101101 00111011001 01001011110 01010010001 01011011110 10000011011

    3.1 结束符

    在需要在对于上述字符的编码,需要在最后加上结束符。结束符为连续 4 个 0 值。加上结束符后,得到的编码如下:

    编码 字符数 CHANDLERGENG 的编码 结束
    0010 000001101 01000101101 00111011001 01001011110 01010010001 01011011110 10000011011 0000

    如果所有的编码加起来不是 8 的倍数,则还需要在后面加上足够的 0。如上面一共有 83bits,所以与 8 的倍数还相差两位,故在最后加上 5 个 0,上表最终的数据变为:
    00100000 01101010 00101101 00111011 00101001 01111001 01001000 10101101 11101000 00110110 00000000

    3.2 补齐符

    如果最后还没有达到我们最大的 Bits 数限制,则需要在编码最后加上补齐符(Padding Bytes)。
    补齐符内容是不停重复两个字节:1110110000010001。这两个二进制转成十进制,分别为 236 与17,具体不知道为什么选这两个值……关于每一个Version的每一种纠错级别的最大Bits限制,可以参看 QR Code Spec 的第35页到44页的 Table-7 一表(笔者参考的是《ISO/IEC 18004》2000版),大致如下图 3.1 所示:


    SouthEast
    图3.1 二维码纠错级别的最大Bits限制(部分)

    上图 3.1 中提到的 codewords,可译为码字,一个码字是一个字节。对于 Version 1 的 H 纠错级别,共需要 26 个码字,即 104bits。现在加上用 0 补全的结束符,已经有了 88bits,故还需要补上 16 bits。补齐后的编码为:

    00100000 01101010 00101101 00111011 00101001 01111001 01001000 10101101 11101000 00110110 00000000 11101100 00010001

    以上数据即为数据码(Data Codewords)

    四. 纠错码

    前文提到了不同的纠错级别(Error Correction Code Level)。有了纠错机制,才可以使得有些二维码有了残缺也可以扫码解析出来,才可以使得二维码中心位置可以供某些商家加上对解析不必要的图标。
    二维码一共有四种纠错级别:

    纠错水平 可被修正容量
    L 7% 码字
    M 15% 码字
    Q 25% 码字
    H 30% 码字

    二维码对数据码加上纠错码的过程,首先要对数据码进行分组,即分成不同的块(Block)。参看如上图 3.1 所示 QR Code Spec 的第35页到44页的 Table-7 中的最下方说明了分组的定义表:


    SouthEast
    图4.1 二维码纠错级别说明(部分)

    对于表中的最后两列的内容:

    • 纠错块个数(Number of error correction blocks):需要划分纠错快的个数;
    • 纠错块码字数(Error Correction Code Per Blocks):每个块中的码字个数,即有多少个字节Bytes;

    表中最下面关于 (c,k,r) 的解释:

    • c:码字总个数;
    • k:数据码个数;
    • r:纠错码容量

    注:

    • c,k,r的关系公式:c=k+2×r
    • 纠错码容量小于纠错码个数的一般

    以上图 4.1 中的 Version 5 + H 纠错机为例:图中红色方框说明共需要 4 个块(上下行各一组,每组 2 个块)。

    第一组的属性:

    • 纠错块个数 = 2:该组中有两个块;
    • (c, k, r) = (33, 11, 11):该组中每个块共有 33 个码字,其中 11 个数据码, 11×2=22 个纠错码;

    第二组的属性:

    • 纠错块个数 = 2:该组中有两个块;
    • (c, k, r) = (34, 12, 11):该组中每个块共有 34 个码字,其中 12 个数据码, 11×2=22 个纠错码;

    具体示例如下表所示,且由于使用二进制会使得表格过大,故转为范围在 0~255 的十进制。其中组 1 的每个块,都有 11 个数据码, 22 个纠错码;组 2 的每个块,都有 12 个数据码,22 个纠错码。

    数据 每个块的纠错码
    1 1

    2
    67 85 70 134 87 38 85 194 119 50 6

    66 7 118 134 242 7 38 86 22 198 199
    199 11 45 115 247 241 223 229 248 154 117 236 38 6 50 17 7 236 213 87 148 235

    177 212 76 133 75 242 238 76 195 230 189 106 248 134 76 40 154 27 195 255 117 129
    2 1

    2
    247 119 50 7 118 134 87 38 82 6 134 151

    194 6 151 50 16 236 17 236 17 236 17 236
    96 60 202 182 124 157 200 134 27 129 209 182 70 85 246 230 247 70 66 247 118 134

    173 24 147 59 33 106 40 255 172 82 2 157 242 33 229 200 238 106 248 134 76 40

    二维码的纠错码主要是通过里德-所罗门纠错算法(Reed-Solomon Error Correction)实现的。

    (关于 Reed-Solomon 算法,现在此处占坑,回头研究了再写上去)

    五. 最终编码

    此时得到了数据,但还不能开始画图,因为二维码还需要将数据码与纠错码的各个字节交替放置。

    5.1 穿插放置

    继续以第四章中给出的示例为例,给出其穿插放置的过程。

    5.1.1 数据码穿插放置

    第四章示例中的数据码如下表所示:

    块数
    块1 67 85 70 134 87 38 85 194 119 50 6
    块2 66 7 118 134 242 7 38 86 22 198 199
    块3 247 119 50 7 118 134 87 38 82 6 134
    块4 194 6 151 50 16 236 17 236 17 236 17

    提取每一列数据:

    • 第一列:67, 66, 247, 194;
    • 第二列:85, 7, 119, 6;
    • ……
    • 第十一列:6, 199, 134, 17;
    • 第十二列:151, 236;

    将上述十二列的数据拼在一起:67, 66, 247, 194, 85, 7, 119, 6,…, 6, 199, 134, 17, 151, 236。

    纠错码如下表所示:

    块数
    块1 199 11 45 115 247 241 223 229 248 154 117
    块2 177 212 76 133 75 242 238 76 195 230 189
    块3 96 60 202 182 124 157 200 134 27 129 209
    块4 173 24 147 59 33 106 40 255 172 82 2

    同样的方法,将 22 列数据放在一起:199, 177, 96, 173, 11, 212, 60, 24, …, 148, 117, 118, 76, 235, 129, 134, 40。

    上述部分即为二维码的数据区。

    5.2 剩余位 (Remainder Bits)

    对于某些 Version 的二维码,得到上面的数据区结果长度依旧不足,需要加上最后的剩余位。比如对于 Version 5 + H 纠错等级的二维码,剩余位需要加 7bits,即加 7 个 0。参看 QR Code Spec 的 Table-1 一表即可查询不同 Version 的剩余位信息,如下图 5.1 所示:


    SouthEast
    图5.1 不同 Version 的剩余位

    六. 二维码的绘制

    终于讲到二维码绘制过程了,绘制的过程按照顺序对图 1.1 中各个重要部分依次讲解。

    6.1 定位图案 (Position Detection Pattern)

    首先在二维码的三个角上绘制定位图案。定位图案与尺寸大小无关,一定是一个 7×7 的矩阵。如下图 6.1 所示:


    SouthEast
    图6.1 定位图案 (Position Detection Pattern)

    6.2 对齐图案 (Alignment Pattern)

    然后绘制对齐图案。对齐图案与尺寸大小无关,一定是一个 5×5 的矩阵。如下图 6.2 所示:


    SouthEast
    图6.2 对齐图案 (Alignment Pattern)

    对齐图案绘制的位置,可参看 QR Code Spec 的 Table-E.1 一表查询,部分内容如下图 6.3 所示:


    SouthEast
    图6.3 对齐图案位置索引表(部分)

    下图 6.4 是上述表格中 Version 8 的一个例子,对于 Version 8 的二维码,行列值在 6, 24, 42 的几个点都会有对齐图案。


    SouthEast
    图6.4 对齐图案例程 1

    下图 6.5 是最近我老妈怂恿我用支付宝抢红包时给我发来的二维码,该二维码中只有一个对齐图案, 故 Version 应在 V2——V6 之间。


    SouthEast
    图6.5 对齐图案例程 2

    6.3 时序图案 (Timing Pattern)

    时序图案是两条连接三个定位图案的线,如下图 6.6 所示:


    SouthEast
    图6.6 时序图案例程 1

    依旧拿支付宝红包的二维码为例,其时序图案如图 6.7 所示:


    QR Code Timing-Pattern_Ex02.png
    图6.7 时序图案例程 2

    这里写图片描述

    6.4 格式信息

    格式信息如下图 6.8 所示:


    SouthEast
    图6.8 格式信息

    格式信息在定位图案周围分布,由于定位图案个数固定为 3 个,且大小固定,故格式信息也是一个固定 15bits 的信息。每个 bit 的位置如下图 6.9 所示:(注:图中的 Dark Module 是固定永远出现的


    SouthEast
    图6.9 格式信息位置

    15bits 中数据,按照 5bits 的数据位 + 10bits 纠错位的顺序排列:

    • 数据位占 5bits:其中 2bits 用于表示使用的纠错等级 (Error Correction Level),3bits 用于表示使用的蒙版 (Mask) 类别;
    • 纠错位占 10bits:主要通过 BCH Code 计算;

    为了减少扫描后图像识别的困难,最后还需要将 15bits 与 101010000010010 做异或 XOR 操作。因为我们在原格式信息中可能存在太多的 0 值(如纠错级别为 00,蒙版 Mask 为 000),使得格式信息全部为白色,这将增加分析图像的困难。

    纠错等级的编码如下图 6.10 的表格所示:


    SouthEast
    图6.10 纠错等级编码

    关于蒙版图案的生成,在后文 6.7 中具体说明。格式信息的示例如下:

    假设存在纠错等级为 M(对应 00),蒙版图案对应 000,5bits 的数据位为 00101,10bits 的纠错位为 0011011100
    则生成了在异或操作之前的 bits 序列为:001010011011100
    101010000010010 做异或 XOR 操作,即得到最终格式信息:100000011001110

    6.5 版本信息 (Version Information)

    对于 Version 7 及其以上的二维码,需要加入版本信息。如下图 6.11 蓝色部分所示:


    SouthEast
    图6.11 版本信息

    版本信息依附在定位图案周围,故大小固定为 18bits。水平竖直方向的填充方式如下图 6.12 所示:


    SouthEast
    图6.12 版本信息填充方式

    18bits 的版本信息中,前 6bits 为版本号 (Version Number),后 12bits 为纠错码 (BCH Bits)。示例如下:

    假设存在一个 Version 为 7 的二维码(对应 6bits 版本号为 000111),其纠错码为 110010010100;
    则版本信息图案中的应填充的数据为:000111110010010100

    6.6 数据码与纠错码

    此后即可填充第五章得到的数据内容了。填充的思想如下图 6.13 的 Version 3 二维码所示,从二维码的右下角开始,沿着红线进行填充,遇到非数据区域,则绕开或跳过。


    SouthEast
    图6.13 二维码数据填充(原始版)

    然而这样难以理解,我们可以将其分为许多小模块,然后将许多小模块串连在一起,如下图 6.14 所示(截取自 QR Code Spec 的图 15):


    SouthEast
    图6.14 二维码数据填充

    小模块可以分为常规模块和非常规模块,每个模块的容量都为 8。常规情况下,小模块都为宽度为 2 的竖直小矩阵,按照方向将 8bits 的码字填充在内。非常规情况下,模块会产生变形。
    填充方式上图 6.14,图中深色区域(如 D1 区域)填充数据码,白色区域(如 E15 区域)填充纠错码。遍历顺序依旧从最右下角的 D1 区域开始,按照蛇形方向(D1→D2→…→D28→E1→E2→…→E16→剩余码)进行小模块的填充,并从右向左交替着上下移动。下面给出若干填充原则:

    原则 1:无论数据的填充方向是向上还是向下,常规模块(即 8bits 数据全在两列内)的排列顺序应是从右向左,如下图 6.15所示;


    SouthEast
    图6.15 常规模块内的填充方向

    原则 2:每个码字的最高有效位(即第7个bit)应置于第一个可用位。对于向上填充的方向,最高有效位应该占据模块的右下角;向下填充的方向,最高有效位占据模块的右上方。
    注:对于某些模块(以下图 6.17 为例),如果前一个模块在右边模块的列内部结束,则该模块成为不规则模块,且与常规模块相比,原本填充方向向上时,最高位应该在右上角,此时则变为左下角;
    原则 3:当一个模块的两列同时遇到对齐图案或时序图案的水平边界时,它将继续在图案的上方或下方延续;
    原则 4:当模块到达区域的上下边界(包括二维码的上下边界、格式信息、版本信息或分隔符)时,码字中任何剩余 bits 将填充在左边的下一列中,且填充方向反转;如下图 6.16 中的两个模块遇到了二维码的上边界,则方向发生变化;


    SouthEast
    图6.16 非常规模块填充方向的改变(举例于 QR Code Spec 图 13)

    原则 5:当模块的右一列遇到对齐图案,或遇到被版本信息占据的区域时,数据位会沿着对齐图案或版本信息旁边的一列继续填充,并形成一个不规则模块。如果当前模块填充结束之前,下一个的两列都可用,则下一个码字的最高有效位应该放在单列中,如下图 6.17 所示:


    SouthEast
    图6.17 模块单列填充

    6.7 蒙版图案

    按照上述思路即可将二维码填充完毕。但是那些点并不均衡,如果出现了大面积的空白或黑块,扫描识别会十分困难,所以按照在前文 6.4 中格式信息的处理思路,对整个图像与蒙版进行蒙版操作(Masking),蒙版操作即为异或 XOR 操作。
    二维码又 8 种蒙版可以使用,如下图 6.18 所示,公式也在图中说明。蒙版只会和数据区进行异或操作,不会影响与格式信息相关的功能区。
    注:选择一个合适的蒙版也是有一定算法的。

    蒙版图案如下图 6.18 所示,对应的产生公式与蒙版 ID 如下图 6.19 的表格所示:


    SouthEast
    图6.18 蒙版图案


    SouthEast
    图6.19 蒙版图案产生公式

    蒙版操作的过程与对比图如下图 6.20 所示,图中最上层是没有经过蒙版操作的原始二维码,其中存在大量黑色区域,难以后续的分析识别。经过两种不同蒙版的处理,可以看到最后生成的二维码变的更加混乱,容易识别。


    SouthEast
    图6.20 蒙版操作示例

    蒙版操作之后,得到的二维码即为最终我们平常看到的结果。

    七. 源码

    笔者原本准备用 C++ 与 OpenCV 写一个二维码解析程序,现在学了二维码的原理后,发现好难。另外网上关于二维码解析与生成的程序基本都是用 Python 写的,笔者又想找个合适机会学习一下 Python,所以这段时间就准备从二维码入手,学习一下 Python 的基础~

    源码及解析笔者会随学习的进度持续更新~

    八. 后记

    笔者学习完毕二维码内容后不禁感叹,二维码规则的制定当真是凝聚了多少研究者的心血。学无止境,在知识的海洋中,当真是需要抱着敬畏之心和谦卑的态度,才能体会到这片海洋的浩瀚。
    研究二维码的过程十分有趣,学到了不少东西,后续过程中笔者会持续更新对二维码的学习心得体会~

    展开全文
  • 二维码生成原理

    2020-03-07 15:08:43
    二维码生成原理及解析代码 自从大街小巷的小商小贩都开始布满了腾讯爸爸和阿里爸爸的二维码之后,我才感觉到我大天朝共享支付的优越性。最近毕...
  • 微信二维码支付,能够生成对应的二维码,扫描该二维码即可进行微信二维码支付
  • 一、二维码简介_二维码基本概念_二维码基本原理 1.二维码又称二维条码,常见的二维码为QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,...
  • 二维码扫码支付原理

    千次阅读 2019-09-26 18:28:29
    线下扫码支付大大的提高了我们付款的效率,今天就主要谈一谈扫码支付的实现流程,让我们享受快捷的同时,也了解其中的原理二维码——信息的载体 说起扫码支付,就不得不提二维码。线下所有的扫码支付都是以扫...
  • 二维码基本原理

    千次阅读 2019-09-25 14:24:10
    矩阵式二维码,最流行莫过于QR CODE,二维码的名称是相对与一维码来说的,比如以前的条形码就是一个“一维码”。它的优点有:二维码存储的数据量更大;可以包含数字、字符,及中文文本等混合内容;有一定的容错性...
  • 交通一卡通二维码支付技术要求

    千次阅读 2018-11-08 12:42:25
    交通一卡通二维码支付技术要求 范围 本技术要求规定了交通一卡通二维码(以下简称“二维码”)支付的应用场景、系统框架及流程、二维码数据结构、信息接口、安全要求、终端要求、手机客户端要求等。 本技术要求...
  • 二维码是我们日常生活中随处可见,支付扫码,登录扫码,添加好友扫码,或者查看某些内容也需要扫码。今天分享一下二维码背后的技术和逻辑,并且通过二维码登录的例子,了解二维码在某些场景中的使用方法。
  • 二维码发展 二维码又称QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息...生成二维码原理 简解 用特定的几何图形按编排规律在二维方向上...
  • 目录 1 引入 ...5 QR code二维码生成流程及原理 5.1 数据编码 5.2 纠错码 5.3 最终编码 5.4 画二维码 5.5 二维码优势 6 个性二维码 7 总结 1 引入 近年来,随着移动互联网的发展,二维...
  • 自[二维码支付](http://www.wiipay.cn/)诞生以来,短短数年,已呈星火燎原之势遍布...对于二维码支付原理,我认为可依据二维码蕴含支付信息(付款用户、支付金额、收单商家)的不同,分为四大类:付款账户二维码支付...
  • 微信支付--商户二维码支付(JAVA)

    千次阅读 2019-01-04 15:06:59
    --微信支付SDK--&amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;amp;lt;dependency&amp;amp;amp;amp;amp;amp;amp;amp;gt; &amp;amp;amp;amp;amp;amp;amp;a
  • 话说,为什么微信支付比支付宝来的晚了那么一点,一句话,那一阵挺忙的,然后就没有时间整理,最近做完支付宝支付,顺便也把微信支付的也整理一下。 这里再吐槽一下,微信支付的DEMO基本为零,很多代码都是从网上...
  • Android二维码原理与优化方向

    万次阅读 多人点赞 2020-03-03 16:37:31
    做过Android的二维码扫描的童鞋可能会遇到过,很多二维码识别不了,或者识别速度慢。一般造成这个识别不出来的原因,大概以下几点: Android手机配置不一样,手机像素高低也有不同,有的手机还不支持自动对焦 环境...
  • 二维码生成以及扫一扫解析二维码原理 1、生成URL,确定要通过二维码传达的信息,也就是通过扫一扫可以获得地址和数据信息 1、// 得到随机数,用随机数得到签名,签名验证身份 String ranString = ...
  • 第一步、解析用户上传的微信支付、QQ钱包、支付宝收款二维码,获取收款链接地址。 第二步、用自己的网站程序生成一张二维码的图片,比如我下面这张图: 这张图的二维码链接大概是这样: http://接口域名/api....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 5,366
精华内容 2,146
关键字:

二维码支付的原理