关于即时通讯:IM扫码登录技术专题四你真的了解二维码吗刨根问底一文掌握

104次阅读

共计 7968 个字符,预计需要花费 20 分钟才能阅读完成。

本文援用了 ELab 团队、腾讯大讲堂两个公众号分享的文章内容,援用内容见文末参考资料,感激原作者的自私分享。

1、引言

对于市面上支流的 IM 来说,跟二维码无关的性能,比方扫码加好友、扫码登陆、扫码加群等,都是很常见的。

这是微信的扫码登录性能:

这是微信的扫码加好友性能:

二维码技术应用起来很简略,本系列的前三篇文章也专门针对 IM 扫码登录这个性能做了具体的分享,但本着学习技术不留死角的习惯,我认为有必要独自学习一下到底什么是二维码(说不定哪天被个刚入行的程序员微微一句“哥,啥是 2 维码”,给问的懵逼了,那时就不仅“头凉”,还会“心梗”…),这也是专门整顿本文的目标所在。

阐明:精确地说,咱们平时见的最多的二维码其实是 QR 码,也就是目前我国利用最为宽泛的一种二维码。为了表述简略,如无特指,本文中所述二维码皆指 QR 码。

学习交换:

  • 即时通讯 / 推送技术开发交换 5 群:215477170 [举荐]
  • 挪动端 IM 开发入门文章:《新手入门一篇就够:从零开发挪动端 IM》
  • 开源 IM 框架源码:https://github.com/JackJiang2…

(本文同步公布于:http://www.52im.net/thread-37…)

2、专题目录

本文是系列文章的第 4 篇,总目录如下:

《IM 扫码登录技术专题(一):微信的扫码登录性能技术原理调试剖析》
《IM 扫码登录技术专题(二):市面支流的扫码登录技术原理调试剖析》
《IM 扫码登录技术专题(三):通俗易懂,IM 扫码登录性能具体原理一篇就够》
《IM 扫码登录技术专题(四):你真的理解二维码吗?刨根问底、一文把握!》(* 本文)

举荐:另一篇《难得干货,揭秘支付宝的 2 维码扫码技术优化实际之路》可一并浏览。

3、二维码的源起

精确地说,咱们平时见的最多的二维码其实是 QR 码,也就是目前我国利用最为宽泛的一种二维码。为了表述简略,如无特指,本文中所述二维码皆指 QR 码。

3.1 时代背景
上个世纪 60 年代之后,日本经济迎来的高速增长期,品种繁多的商品的超市开始在城市中呈现。

过后超市应用的现金出纳机要靠手动输出商品价格,因而负责现金出纳的人经常会因手段的麻痹和“腱鞘炎”而苦恼。

“是否加重超市收款员的累赘呢?”

条形码的呈现解决了这一苦恼。因为 POS 零碎的胜利开发,仅通过光感读取条形码,价格就会主动显示在出纳机上,同时读取的商品信息还能传送到计算机上。

如此一来,条形码得以遍及,但新的课题又随之而来。问题在于条形码的容量无限,英文数字最多只能包容 20 个字。

“编码自身要是可能含有更多的信息就好了”、“心愿具备汉字和假名的解决性能”。

过后正在从事条形码读取机研发的 Denso Wave 公司(这家公司是日本电装株式会社(Denso Corporation)旗下的子公司)理解到了这类需要。在这一背景下,研发小组怀着“肯定要满足客户需要”的宿愿,投入到了新的二维码的研发之中。

3.2 研发 2 人组
“过后其余公司研发的二维码把重点放在了信息量的纳入上”,过后负责二维码研发的腾弘原(Masahiro Hara) 回首当年如是说。


▲ 上图中的“怪大叔”就是腾弘原(Masahiro Hara)

条形码只能横向(一维)存储信息,相比之下,二维码则能纵横二维存储信息。腾弘原的思考是,除了可能包容大量的信息外,“研发的编码还要便于读取”,据此投入了新的二维码的研发之中。研发小组仅仅只有两人。

3.3 技术难题
腾弘原 (Masahiro Hara) 的研发小组面临的最大技术难题,是如何实现高速读取。

有一天,腾弘原的脑海里浮现出这样一个思路:“附上‘此处有编码’这样的地位信息会怎么?”

于是想到的是回字形的“定位图案”。将这一图形放入二维码中,便可实现其余公司无奈模拟的高速读取。


▲ 上图中三个角的回字型图案就是“定位图案”


▲“定位图案”黑白色块比例是 1:1:3:1:1

3.4“定位图案”为何是回字型?
定位图案为何要应用那种回字型的呢?

腾弘原解释说:“因为这种图形在票据等当中呈现频率最小”。

也就是说:如果左近有同样的图形,读取机就会将其误认为是编码,为了避免这种误读,定位图案必须是惟一的图形。

通过全面思考:腾弘原等人决定将印刷在广告单、杂志、纸板等处的绘图和文字全副变成黑白两色,对其面积比率进行彻底的考察。

研发小组日以继夜地对有数的印刷品进行考察的后果,终于查明了印刷品中“最不罕用的比率”,即 1︰1︰3︰1︰1。

这样:便确定了定位图案黑白局部的宽幅比率。所造成的构造是,扫描线能够从 360 度方向扫描,无论从哪个方向扫描,一旦扫到其独特的比率,便可计算出编码的地位。


▲回字型“定位图案”使得无论从哪个方向扫描都能失常辨认

研发我的项目启动后通过一年半的工夫,在经验了几多波折之后,可包容约 7000 个数字的二维码(精确地说是 QR 码)终于诞生了。其特点是能进行汉字解决,大容量,而且读取速度比其余编码快 10 倍以上。

3.5 二维码的专利费
既然二维码(精确地说是 QR 码)这货色是由公司和集体钻研实现,那为时至今日它的专利费到底该怎么收取呢?

坊间风闻,腾弘原说了这么一句话:“这种技术其实轻易找个网络工具就能实现,所以这么简略的货色,我就不收专利费啦。”。

当然以上只是风闻,应该不是真的。

实际上 Denso Wave 公司领有 QR 码的专利权,齐全能够向应用 QR 码的公司或集体免费专利费,但 Denso Wave 公司明确示意不会行使这项权力。这是开始研发当初就定下来的方针,也反映了研发者的想法:“心愿能有更多的人应用 QR 码”。

于是无需老本、可放心使用的 QR 码现已作为“公共的编码”,在全世界失去了宽泛的利用。

4、二维码的长处

回到技术自身,用古代的视角先来总结一下二维码到底有什么有点。

二维码呈现之前,在须要应用相似编码的场景时,采纳的都是一维码(条形码)。

然而条形码承载的信息太少,只能用于一些很简略的场景,因而条形码除了用于商品等信息,并没有宽泛风行。

总结一下,二维码具备以下长处:

1)信息容量大:可包容多达 1850 个大写字母或 2710 个数字或 1108 个字节,或 500 多个汉字,比一般条码信息容量约高几十倍;
2)编码范围广:该条码能够把图片、声音、文字、签字、指纹等能够数字化的信息进行编码,用条码示意进去;
3)容错能力强:具备纠错性能,这使得二维条码因穿孔、污损等引起部分损坏时,照样能够正确失去识读,损毁面积达 50% 仍可复原信息;
4)译码可靠性:它比一般条码译码错误率百万分之二要低得多,误码率不超过千万分之一;
5)可引入加密:保密性、防伪性好;
6)应用成本低:易制作,长久耐用。

5、初识二维码

咱们能够先试着生成一个二维码,演示地址是:https://kazuhikoarase.github….。

如上图所示:能够发现,二维码有 4 个可变项,其中次要的 2 个为版本和容错率。

1)版本(TypeNumber):

一共有 40 个尺寸,对应 40 个版本;Version1 是 21*21 的矩形,之后每减少一个版本,就减少 4 的尺寸,即(v-1)4+21,最高是 Version40,177177 的正方形。

2)容错率(ErrorCorrectionLevel):

二维码容错率即是指二维码图标被遮挡多少后,仍能够被扫描进去的能力。容错率越高,则二维码图片能被遮挡的局部越多。

二维码有 4 个容错等级:

依据以上配置不同,雷同的内容,在不同的配置下产生的二维码不一样,但扫出的内容是一样的。

6、二难码的设计原理

日常咱们看到的二维码就是一张由黑白色块混合在一起的一张图片,咱们必定也晓得这些黑白色块就是内容的某种编码,但其实除了内容外,二维码还有许多其余辅助扫码辨认的信息。

如上图所示,按右侧标识的从上到下的程序,别离是功能区和数据区。

6.1 功能区
功能区的次要内容是:

1)地位探测图形:位于左上、左下、右上的三个矩形,能够说是二维码最重要的组成部分;
2)地位探测图形分隔符:地位探测图形四周的白边,用于宰割地位探测图形和数据。
3)定位图形:三个地位探测图形之间的两根“线”,用于确定二维码符号中模块的坐标(相当于坐标轴);
4)校对图形:用于校对定位(只有版本 2 以上有),版本越高个数越多,以校对可能产生的定位偏移。
地位探测图形的作用次要是:

1)确定二维码的搁置方向:不论顺着扫倒着扫,都能够精确找到第一个编码字符的地位(左上矩形的左边);如果任一矩形被遮挡,扫描设施将无奈定位;
2)确定编码字符的边界:确定编码字符的上下左右边界,不被四周其余信息烦扰。
从网上搜二维码图片,能够察看下,这些二维码都具备地位探测图形、地位探测图形分隔符及定位图形。

其中第三幅,定位图形不太对,也的确就扫不进去:

6.2 数据区
数据区的次要内容是:

1)格局信息:寄存包含纠错码类型、掩码类型等信息;
2)数据和纠错码字:最次要的局部,用于存放数据和纠错信息。
除掉定位区以及格局信息,数据和纠错码字的排布如下:

7、二维码的生成流程

在所有数据都实现搁置之后,还有一步操作:增加掩码。

掩码次要是为了防止,如果呈现大面积的空白或黑块,导致咱们扫描辨认的艰难。

罕用的掩码如下:

数据通过掩码后,根本不会再呈现大面积的黑块和白块,利于扫描。

注:掩码只会与数据区进行 XOR,不会影响功能区。

8、Show me the code

只有遵循以上二维码的标准,生成对应的二维码图形即可,具体实现逻辑不影响。

这里咱们参考 jquery-qrcode,简略看下实现。

次要流程如下:

makeImpl : function(test, maskPattern) {

this.moduleCount = this.typeNumber * 4 + 17;

this.modules = newArray(this.moduleCount);

for(varrow = 0; row < this.moduleCount; row++) {this.modules[row] = newArray(this.moduleCount);

  for(varcol = 0; col < this.moduleCount; col++) {this.modules[row][col] = null;//(col + row) % 3;

  }

}

this.setupPositionProbePattern(0, 0);// 地位探测图形

this.setupPositionProbePattern(this.moduleCount - 7, 0);// 地位探测图形

this.setupPositionProbePattern(0, this.moduleCount - 7);// 地位探测图形

this.setupPositionAdjustPattern(); // 校对图形

this.setupTimingPattern(); // 定位图形(坐标轴)this.setupTypeInfo(test, maskPattern); // 版本信息

if(this.typeNumber >= 7) {this.setupTypeNumber(test);

}

if(this.dataCache == null) {this.dataCache = QRCode.createData(this.typeNumber, this.errorCorrectLevel, this.dataList); // 生成数据

}

this.mapData(this.dataCache, maskPattern); // 退出掩码

},

生成二维数据后,再把点一一绘制进去即可:

var createCanvas = function(){

  // create the qrcode itself

  var qrcode  = new QRCode(options.typeNumber, options.correctLevel);

  qrcode.addData(options.text);

  qrcode.make();

  // create canvas element

  var canvas  = document.createElement('canvas');

  canvas.width  = options.width;

  canvas.height = options.height;

  var ctx   = canvas.getContext('2d');

  // compute tileW/tileH based on options.width/options.height

  var tileW = options.width  / qrcode.getModuleCount();

  var tileH = options.height / qrcode.getModuleCount();

  // draw in the canvas

  for(varrow = 0; row < qrcode.getModuleCount(); row++ ){for( varcol = 0; col < qrcode.getModuleCount(); col++ ){ctx.fillStyle = qrcode.isDark(row, col) ? options.foreground : options.background;

      var w = (Math.ceil((col+1)*tileW) - Math.floor(col*tileW));

      var h = (Math.ceil((row+1)*tileH) - Math.floor(row*tileH));

      ctx.fillRect(Math.round(col*tileW),Math.round(row*tileH), w, h); 

    }

  }

  // return just built canvas

  return canvas;

}

9、艺术二维码

日常咱们见到的二维码都是黑白的,但其实二维码能够多姿多彩。

这里有很多款式,能够试一试:https://qrbtf.com/。

二维码之所以能够五光十色,是因为二维码的有用信息只是 0 和 1,至于 0 和 1 用什么信息表白,只有扫码软件能够辨认就行。目前的扫码软件个别都是对图片进行灰度解决,所以二维码上的点无论如何表白,只有通过灰度解决后 0 和 1 没有颠倒,则信息不会出错,不会影响扫码后果。

艺术二维码实现起来也不难,只有辨别特定的数据区,并用特定的图片渲染即可,有趣味能够参考:https://github.com/252860883/…。

更简略一点的,也能够间接升高黑白透明度,背景渲染特定的图片:

如果只是网页上显示,还能够做成 gif 动图模式(这里就不贴样本了)。

不过,艺术二维码因为色彩更丰盛烦扰信息更多,因而相比黑白二维码,艺术二维码对扫描软件的要求也更高。

10、微信小程序码

小程序码和二维码尽管看起来齐全不一样,然而它们的设计思维及生成流程是根本一样的。

如上图所示,微信小程序码的特色有:

1)具备地位探测图形;
2)反对 3 种容量:36 射线、54 射线和 72 射线;
3)具备 L、M、Q、H 4 种容错级别;
4)掩码操作平均 0、1 码点。

题外话:理解二维码的原理后,其实咱们本人也能够手画二维码。

11、一个乏味的问题:“二维码会被用完吗?”

这个问题很简略,答案是:会。

因为二维码的尺寸是无限的,那二维码的数量就是无限的。

然而用完所有的二维码,须要很长很长的工夫。。。

当初的二维码有 40 个官网版本,从 Version1-40,最小为 2121、最大为 177177 矩阵。

其中,以微信名片为例,就是 37×37 的矩阵规格,微信的付款码是 25×25 的矩阵规格。为了不便了解,咱们用方块作为矩阵单位。

▲ 上图就是微信名片(即 37×37 矩阵的二维码)

如何计算,各矩阵中生成的二维码个数?

咱们来举个例子:

如上图所示的四宫格,每个格子有两种色彩变动,请问一个四宫格能够组合出多少个图形?

答案是:一个格子两种色彩,那就是两种可能,两个格子就是四种可能,三个格子就是 8 种可能,四个格子就是 16 种可能。所以,四宫格可能组成 2^4,共 16 个图形。

以此类推,以微信的 25X25 付款码为例:

每一排有 25 个方块,共 25 列,除去定位用的方块和冗余纠错的方块等,还剩下 478 个方块。依照二进制,每个方块只有黑或白两种抉择,所以 478 个小方块实践上一共能够组合 2^478 个二维码。

也就是一个 25X25 规格尺寸的二维码能够生成:

780437137578998057845399307448291576437149535666242787714789239906342934704941405030076525765872992789956732780351655723861993919822071326572544 个二维码。

大家能够尝试念进去大略多少个?

依据疫情期间 1400 亿个二维码的数量来计算,假如微信一年会用掉 6000 亿个二维码。那微信用掉 25X25 这一个尺寸产生的二维码须要多少年呢?

咱们来算一下:2^478/6000 亿 =1.301×10^132 年(超多亿亿亿亿年)。

所以:尽管实践上二维码的确有用完的那一天,但实际上这个工夫帮长了,以至于咱们当初齐全能够不必思考!

12、参考资料

[1] 难得干货,揭秘支付宝的 2 维码扫码技术优化实际之路
[2] 你每天都扫的二维码,晓得它是怎么来的么?
[3] 二维码,你真的理解吗?
[4] 二维码会被人类扫完吗?
[5] QR 码的成功之路
[6] 乏味的二维码

附录:更多 IM 相干入门级文章

《新手入门一篇就够:从零开发挪动端 IM》
《技术往事:扭转世界的 TCP/IP 协定(宝贵多图、手机慎点)》
《通俗易懂 - 深刻了解 TCP 协定(上):实践根底》
《网络编程懒人入门 (一):疾速了解网络通信协定(上篇)》
《网络编程懒人入门(二):疾速了解网络通信协定(下篇)》
《脑残式网络编程入门(一):跟着动画来学 TCP 三次握手和四次挥手》
《脑残式网络编程入门(二):咱们在读写 Socket 时,到底在读写什么?》
《网络编程入门从未如此简略(一):如果你来设计网络,会怎么做?》
《网络编程入门从未如此简略(二):如果你来设计 TCP 协定,会怎么做?》
《IM 开发者的零根底通信技术入门(十一):为什么 WiFi 信号差?一文即懂!》
《IM 开发者的零根底通信技术入门(十二):上网卡顿?网络掉线?一文即懂!》
《IM 开发者的零根底通信技术入门(十三):为什么手机信号差?一文即懂!》
《IM 开发者的零根底通信技术入门(十四):高铁上无线上网有多难?一文即懂!》
《从根上了解高性能、高并发(一):深刻计算机底层,了解线程与线程池》
《从根上了解高性能、高并发(二):深刻操作系统,了解 I / O 与零拷贝技术》
《史上最强 Java NIO 入门:放心从入门到放弃的,请读这篇!》
《网页端 IM 通信技术疾速入门:短轮询、长轮询、SSE、WebSocket》
《搞懂古代 Web 端即时通讯技术一文就够:WebSocket、socket.io、SSE》
《一套海量在线用户的挪动端 IM 架构设计实际分享(含具体图文)》
《一套原创分布式即时通讯(IM) 零碎实践架构计划》
《一套亿级用户的 IM 架构技术干货(上篇):整体架构、服务拆分等》
《一套亿级用户的 IM 架构技术干货(下篇):可靠性、有序性、弱网优化等》
《即时通讯音视频开发(十八):详解音频编解码的原理、演进和利用选型》
《即时通讯音视频开发(十九):零根底,史上最艰深视频编码技术入门》
《零根底入门:实时音视频技术基础知识全面盘点》
《零根底 IM 开发入门(一):什么是 IM 零碎?》
《零根底 IM 开发入门(二):什么是 IM 零碎的实时性?》
《零根底 IM 开发入门(三):什么是 IM 零碎的可靠性?》
《零根底 IM 开发入门(四):什么是 IM 零碎的音讯时序一致性?》
《开源挪动端 IM 技术框架 MobileIMSDK:疾速入门》

本文已同步公布于“即时通讯技术圈”公众号。
同步公布链接是:http://www.52im.net/thread-37…

正文完
 0