-
日常使用的二维码知多少,从数学的角度对二维码图案进行解析
2021-02-18 14:42:09首先,我们需要对数据码进行分组,也就是分成不同的Block,然后对各个Block进行纠错编码,对于如何分组,我们可以查看QR Code Spec的第33页到44页的Table-13到Table-22的定义表。注意最后两列: Number of Error ...前言
什么是二维码?
二维码又称QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型:比如:字符,数字,日文,中文等等。二维码图片生成的相关细节,类似于一个密码算法。
关于QR Code Specification,可参看这个PDF:http://raidenii.net/files/datasheets/misc/qr_code.pdf
基础知识
首先,我们先说一下二维码一共有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 的正方形。
下面我们看看一个二维码的样例:
定位图案
-
Position Detection Pattern是定位图案,用于标记二维码的矩形大小。这三个定位图案有白边叫Separators for Postion Detection Patterns。之所以三个而不是四个意思就是三个就可以标识一个矩形了。
-
Timing Patterns也是用于定位的。原因是二维码有40种尺寸,尺寸过大了后需要有根标准线,不然扫描的时候可能会扫歪了。
-
Alignment Patterns 只有Version 2以上(包括Version2)的二维码需要这个东东,同样是为了定位用的。
功能性数据
-
Format Information 存在于所有的尺寸中,用于存放一些格式化数据的。
-
Version Information 在 >= Version 7以上,需要预留两块3 x 6的区域存放一些版本信息。
数据码和纠错码
-
除了上述的那些地方,剩下的地方存放 Data Code 数据码 和 Error Correction Code 纠错码。
数据编码
我们先来说说数据编码。QR码支持如下的编码:
Numeric mode 数字编码
从0到9。如果需要编码的数字的个数不是3的倍数,那么,最后剩下的1或2位数会被转成4或7bits,则其它的每3位数字会被编成 10,12,14bits,编成多长还要看二维码的尺寸(下面有一个表Table 3说明了这点)
Alphanumeric mode 字符编码
包括 0-9,大写的A到Z(没有小写),以及符号$ % * + – . / : 包括空格。这些字符会映射成一个字符索引表。如下所示:(其中的SP是空格,Char是字符,Value是其索引值) 编码的过程是把字符两两分组,然后转成下表的45进制,然后转成11bits的二进制,如果最后有一个落单的,那就转成6bits的二进制。而编码模式和字符的个数需要根据不同的Version尺寸编成9, 11或13个二进制(如下表中Table 3)
Byte mode 字节编码
可以是0-255的ISO-8859-1字符。有些二维码的扫描器可以自动检测是否是UTF-8的编码。
Kanji mode 日文编码
也是双字节编码。同样,也可以用于中文编码。日文和汉字的编码会减去一个值。如:在0X8140 to 0X9FFC中的字符会减去8140,在0XE040到0XEBBF中的字符要减去0XC140,然后把结果前两个16进制位拿出来乘以0XC0,然后再加上后两个16进制位,最后转成13bit的编码。如下图示例:
Extended Channel Interpretation (ECI) mode
主要用于特殊的字符集。并不是所有的扫描器都支持这种编码。
Structured Append mode
用于混合编码,也就是说,这个二维码中包含了多种编码格式。
FNC1 mode
这种编码方式主要是给一些特殊的工业或行业用的。比如GS1条形码之类的。
简单起见,后面三种不会在本文 中讨论。
下面两张表中,
-
Table 2 是各个编码格式的“编号”,这个东西要写在Format Information中。注:中文是1101
-
Table 3 表示了,不同版本(尺寸)的二维码,对于,数字,字符,字节和Kanji模式下,对于单个编码的2进制的位数。(在二维码的规格说明书中,有各种各样的编码规范表,后面还会提到)
示例
示例一:数字编码
在Version 1的尺寸下,纠错级别为H的情况下,编码:01234567
1. 把上述数字分成三组: 012 345 67
2. 把他们转成二进制: 012 转成 0000001100;345 转成 0101011001;67 转成 1000011。
3. 把这三个二进制串起来: 0000001100 0101011001 1000011
4. 把数字的个数转成二进制 (version 1-H是10 bits ): 8个数字的二进制是 0000001000
5. 把数字编码的标志0001和第4步的编码加到前面: 0001 0000001000 0000001100 0101011001 1000011
示例二:字符编码
在Version 1的尺寸下,纠错级别为H的情况下,编码: AC-42
1. 从字符索引表中找到 AC-42 这五个字条的索引 (10,12,41,4,2)
2. 两两分组: (10,12) (41,4) (2)
3.把每一组转成11bits的二进制:
(10,12) 10*45+12 等于 462 转成 00111001110
(41,4) 41*45+4 等于 1849 转成 11100111001
(2) 等于 2 转成 0000104. 把这些二进制连接起来:00111001110 11100111001 000010
5. 把字符的个数转成二进制 (Version 1-H为9 bits ): 5个字符,5转成 000000101
6. 在头上加上编码标识 0010 和第5步的个数编码: 0010 000000101 00111001110 11100111001 000010
结束符和补齐符
假如我们有个HELLO WORLD的字符串要编码,根据上面的示例二,我们可以得到下面的编码,
编码 字符数 HELLO WORLD的编码 0010 000001011 01100001011 01111000110 10001011100 10110111000 10011010100 001101 我们还要加上结束符:
编码 字符数 HELLO WORLD的编码 结束 0010 000001011 01100001011 01111000110 10001011100 10110111000 10011010100 001101 0000 按8bits重排
如果所有的编码加起来不是8个倍数我们还要在后面加上足够的0,比如上面一共有78个bits,所以,我们还要加上2个0,然后按8个bits分好组:
00100000 01011011 00001011 01111000 11010001 01110010 11011100 01001101 01000011 01000000
补齐码(Padding Bytes)
最后,如果如果还没有达到我们最大的bits数的限制,我们还要加一些补齐码(Padding Bytes),Padding Bytes就是重复下面的两个bytes:11101100 00010001 (这两个二进制转成十进制是236和17,我也不知道为什么,只知道Spec上是这么写的)关于每一个Version的每一种纠错级别的最大Bits限制,可以参看QR Code Spec的第28页到32页的Table-7一表。
假设我们需要编码的是Version 1的Q纠错级,那么,其最大需要104个bits,而我们上面只有80个bits,所以,还需要补24个bits,也就是需要3个Padding Bytes,我们就添加三个,于是得到下面的编码:
00100000 01011011 00001011 01111000 11010001 01110010 11011100 01001101 01000011 01000000 11101100 00010001 11101100
上面的编码就是数据码了,叫Data Codewords,每一个8bits叫一个codeword,我们还要对这些数据码加上纠错信息。
纠错码
上面我们说到了一些纠错级别,Error Correction Code Level,二维码中有四种级别的纠错,这就是为什么二维码有残缺还能扫出来,也就是为什么有人在二维码的中心位置加入图标。
错误修正容量 L水平 7%的字码可被修正 M水平 15%的字码可被修正 Q水平 25%的字码可被修正 H水平 30%的字码可被修正 那么,QR是怎么对数据码加上纠错码的?首先,我们需要对数据码进行分组,也就是分成不同的Block,然后对各个Block进行纠错编码,对于如何分组,我们可以查看QR Code Spec的第33页到44页的Table-13到Table-22的定义表。注意最后两列:
-
Number of Error Code Correction Blocks :需要分多少个块。
-
Error Correction Code Per Blocks:每一个块中的code个数,所谓的code的个数,也就是有多少个8bits的字节。
举个例子:上述的Version 5 + Q纠错级:需要4个Blocks(2个Blocks为一组,共两组),头一组的两个Blocks中各15个bits数据 + 各 9个bits的纠错码(注:表中的codewords就是一个8bits的byte)(再注:最后一例中的(c, k, r )的公式为:c = k + 2 * r,因为后脚注解释了:纠错码的容量小于纠错码的一半)
下图给一个5-Q的示例(因为二进制写起来会让表格太大,所以,我都用了十进制,我们可以看到每一块的纠错码有18个codewords,也就是18个8bits的二进制数)
组 块 数据 对每个块的纠错码 1 1 67 85 70 134 87 38 85 194 119 50 6 18 6 103 38 213 199 11 45 115 247 241 223 229 248 154 117 154 111 86 161 111 39 2 246 246 66 7 118 134 242 7 38 86 22 198 199 146 6 87 204 96 60 202 182 124 157 200 134 27 129 209 17 163 163 120 133 2 1 182 230 247 119 50 7 118 134 87 38 82 6 134 151 50 7 148 116 177 212 76 133 75 242 238 76 195 230 189 10 108 240 192 141 2 70 247 118 86 194 6 151 50 16 236 17 236 17 236 17 236 235 159 5 173 24 147 59 33 106 40 255 172 82 2 131 32 178 236 注:二维码的纠错码主要是通过Reed-Solomon error correction(里德-所罗门纠错算法)来实现的。对于这个算法,对于我来说是相当的复杂,里面有很多的数学计算,比如:多项式除法,把1-255的数映射成2的n次方(0<=n<=255)的伽罗瓦域Galois Field之类的神一样的东西,以及基于这些基础的纠错数学公式,因为我的数据基础差,对于我来说太过复杂,所以我一时半会儿还有点没搞明白,还在学习中,所以,我在这里就不展开说这些东西了。还请大家见谅了。
最终编码
穿插放置
如果你以为我们可以开始画图,你就错了。二维码的混乱技术还没有玩完,它还要把数据码和纠错码的各个codewords交替放在一起。如何交替呢,规则如下:
对于数据码:把每个块的第一个codewords先拿出来按顺度排列好,然后再取第一块的第二个,如此类推。如:上述示例中的Data Codewords如下:
块 1 67 85 70 134 87 38 85 194 119 50 6 18 6 103 38 块 2 246 246 66 7 118 134 242 7 38 86 22 198 199 146 6 块 3 182 230 247 119 50 7 118 134 87 38 82 6 134 151 50 7 块 4 70 247 118 86 194 6 151 50 16 236 17 236 17 236 17 236 我们先取第一列的:67, 246, 182, 70
然后再取第二列的:67, 246, 182, 70, 85,246,230 ,247
如此类推:67, 246, 182, 70, 85,246,230 ,247 ……… ……… ,38,6,50,17,7,236
对于纠错码,也是一样:
块 1 213 199 11 45 115 247 241 223 229 248 154 117 154 111 86 161 111 39 块 2 87 204 96 60 202 182 124 157 200 134 27 129 209 17 163 163 120 133 块 3 148 116 177 212 76 133 75 242 238 76 195 230 189 10 108 240 192 141 块 4 235 159 5 173 24 147 59 33 106 40 255 172 82 2 131 32 178 236 和数据码取的一样,得到:213,87,148,235,199,204,116,159,…… …… 39,133,141,236
然后,再把这两组放在一起(纠错码放在数据码之后)得到:
67, 246, 182, 70, 85, 246, 230, 247, 70, 66, 247, 118, 134, 7, 119, 86, 87, 118, 50, 194, 38, 134, 7, 6, 85, 242, 118, 151, 194, 7, 134, 50, 119, 38, 87, 16, 50, 86, 38, 236, 6, 22, 82, 17, 18, 198, 6, 236, 6, 199, 134, 17, 103, 146, 151, 236, 38, 6, 50, 17, 7, 236, 213, 87, 148, 235, 199, 204, 116, 159, 11, 96, 177, 5, 45, 60, 212, 173, 115, 202, 76, 24, 247, 182, 133, 147, 241, 124, 75, 59, 223, 157, 242, 33, 229, 200, 238, 106, 248, 134, 76, 40, 154, 27, 195, 255, 117, 129, 230, 172, 154, 209, 189, 82, 111, 17, 10, 2, 86, 163, 108, 131, 161, 163, 240, 32, 111, 120, 192, 178, 39, 133, 141, 236
这就是我们的数据区。
Remainder Bits
最后再加上Reminder Bits,对于某些Version的QR,上面的还不够长度,还要加上Remainder Bits,比如:上述的5Q版的二维码,还要加上7个bits,Remainder Bits加零就好了。关于哪些Version需要多少个Remainder bit,可以参看QR Code Spec的第15页的Table-1的定义表。
画二维码图
Position Detection Pattern
首先,先把Position Detection图案画在三个角上。(无论Version如何,这个图案的尺寸就是这么大)
Alignment Pattern
然后,再把Alignment图案画上(无论Version如何,这个图案的尺寸就是这么大)
关于Alignment的位置,可以查看QR Code Spec的第81页的Table-E.1的定义表(下表是不完全表格)
下图是根据上述表格中的Version8的一个例子(6,24,42)
Timing Pattern
接下来是Timing Pattern的线(这个不用多说了)
Format Information
再接下来是Formation Information,下图中的蓝色部分。
Format Information是一个15个bits的信息,每一个bit的位置如下图所示:(注意图中的Dark Module,那是永远出现的)
这15个bits中包括:
-
5个数据bits:其中,2个bits用于表示使用什么样的Error Correction Level, 3个bits表示使用什么样的Mask
-
10个纠错bits。主要通过BCH Code来计算
然后15个bits还要与101010000010010做XOR操作。这样就保证不会因为我们选用了00的纠错级别和000的Mask,从而造成全部为白色,这会增加我们的扫描器的图像识别的困难。
下面是一个示例:
关于Error Correction Level如下表所示:
关于Mask图案如后面的Table 23所示。
Version Information
再接下来是Version Information(版本7以后需要这个编码),下图中的蓝色部分。
Version Information一共是18个bits,其中包括6个bits的版本号以及12个bits的纠错码,下面是一个示例:
而其填充位置如下:
数据和数据纠错码
然后是填接我们的最终编码,最终编码的填充方式如下:从左下角开始沿着红线填我们的各个bits,1是黑色,0是白色。如果遇到了上面的非数据区,则绕开或跳过。
掩码图案
这样下来,我们的图就填好了,但是,也许那些点并不均衡,如果出现大面积的空白或黑块,会告诉我们扫描识别的困难。所以,我们还要做Masking操作(靠,还嫌不复杂)QR的Spec中说了,QR有8个Mask你可以使用,如下所示:其中,各个mask的公式在各个图下面。所谓mask,说白了,就是和上面生成的图做XOR操作。Mask只会和数据区进行XOR,不会影响功能区。(注:选择一个合适的Mask也是有算法的)
其Mask的标识码如下所示:(其中的i,j分别对应于上图的x,y)
下面是Mask后的一些样子,我们可以看到被某些Mask XOR了的数据变得比较零散了。
Mask过后的二维码就成最终的图了。
好了,大家可以去尝试去写一下QR的编码程序,当然,你可以用网上找个Reed Soloman的纠错算法的库,或是看看别人的源代码是怎么实现这个繁锁的编码。
-
-
Android中采用Pull解析器对XML文件进行解析
2013-01-15 13:20:00一、基本介绍Android中已经集成了xmlpull解析器,所以使用XmlPullParser类非常方便,不需要从外部导入所依赖的Jar包,Pull解析器在解析xml文件的性能上是非常优秀的。 二、例子 读取到xml的声明返回数字0 START_...一、基本介绍
Android中已经集成了xmlpull解析器,所以使用XmlPullParser类非常方便,不需要从外部导入所依赖的Jar包,Pull解析器在解析xml文件的性能上是非常优秀的。二、例子
读取到xml的声明返回数字0 START_DOCUMENT;
读取到xml的结束返回数字1 END_DOCUMENT ;
读取到xml的开始标签返回数字2 START_TAG
读取到xml的结束标签返回数字3 END_TAG
读取到xml的文本返回数字4 TEXT.xml文件
- <?xmlversion="1.0"encoding="UTF-8"?>
- <people>
- <personid="001">
- <name>XY1</name>
- <age>22</age>
- </person>
- <personid="002">
- <name>XY2</name>
- <age>22</age>
- </person>
- </people>
.解析类
- publicclassPersonService
- {
- publicListgetPeople(InputStreamxml)throwsException
- {
- Listlst=null;
- Personperson=null;
- //获得pull解析器工厂
- XmlPullParserFactorypullParserFactory=XmlPullParserFactory.newInstance();
- //获取XmlPullParser的实例
- XmlPullParserpullParser=pullParserFactory.newPullParser();
- //设置需要解析的XML数据
- pullParser.setInput(xml,"UTF-8");
- //取得事件
- intevent=pullParser.getEventType();
- //若为解析到末尾
- while(event!=XmlPullParser.END_DOCUMENT)//文档结束
- {
- //节点名称
- StringnodeName=pullParser.getName();
- switch(event)
- {
- caseXmlPullParser.START_DOCUMENT://文档开始
- lst=newArrayList();
- break;
- caseXmlPullParser.START_TAG://标签开始
- if("person".equals(nodeName))
- {
- Stringid=pullParser.getAttributeValue(0);
- person=newPerson();
- person.setId(id);
- }
- if("name".equals(nodeName))
- {
- Stringname=pullParser.nextText();
- person.setName(name);
- }
- if("age".equals(nodeName))
- {
- intage=Integer.valueOf(pullParser.nextText());
- person.setAge(age);
- }
- break;
- caseXmlPullParser.END_TAG://标签结束
- if("person".equals(nodeName))
- {
- lst.add(person);
- person=null;
- }
- break;
- }
- event=pullParser.next();//下一个标签
- }
- returnlst;
- }
- }
-
数字滤波器回顾与解析
2016-11-27 18:38:57它可以对输入的离散信号进行一系列运算处理,从输入的信号中获得所需要的信息。数字滤波器的系统函数通常表示为 数字滤波器分为有限冲激响应数字滤波器,即FIR数字滤波器和无限冲激响应,即IIR数字滤波器。...1.综述
数字滤波器是一个离散的系统。它可以对输入的离散信号进行一系列运算处理,从输入的信号中获得所需要的信息。数字滤波器的系统函数通常表示为
数字滤波器分为有限冲激响应数字滤波器,即FIR数字滤波器和无限冲激响应,即IIR数字滤波器。从公式的角度来看,FIR数字滤波器的a(i)始终为零;IIR数字滤波器a(i)至少有一个非零。
2.IIR滤波器
IIR数字滤波器具有下面几个特点:
(1)系统的单位冲激响应h(n)为无限长的;
(2)系统函数H(z)在有限z平面上有极点存在;
(3)结构上存在着输出到输入的反馈,也就是结构上是递归型的。
IIR滤波器的设计就是在给定的技术指标下去确定滤波器的阶数N和系数{ a,b}。在已满足给定的技术指标下,应选用阶数尽可能低的滤波器,因为滤波器的阶数越低,在实现时成本就越低。
在设计IIR滤波器时,最常用的方法是利用模拟滤波器来设计数字滤波器。其原因为:
(1)模拟滤波器的设计技术相对成熟,可以广泛利用;
(2)模拟滤波器有大量的参考程序和表格;
(3)它的解可以为闭合形式的。3.FIR滤波器
有限长单位冲激响应滤波器,即 FIR 数字滤波器具有下面几个特点:
( 1)系统的单位冲激响应 h(n)在有限个 n 值处不为零;
( 2)系统函数 H(z)在|z|>0 处收敛,在|z|<=0 处只有零,即有限 z 平面上只有零点,全部极点都在 z=0 处(因果系统)
( 3)没有输出到输入的反馈,但有些结构中(例如频率抽样结构)也包含有反馈的递归部分
FIR 滤波器是指在有限范围内系统的单位脉冲响应 h[k],仅有非零值的滤波器。 M 阶 FIR 滤波器的系统函数 H(z)为:其中 H(z)是z的 M 阶多项式,在有限的 z 平面内 H(z)有 M 个零点,在 z 平面原点 z=0 有 M 个极点!
FIR 滤波器的频率响应 H(jΩ):
它的另外一种表示方法为:
前者代表滤波器的幅频响应,后者代表滤波器的相频响应!
若系统的相位响应φ(Ω)满足下面的条件:
即系统的群延迟是一个与频率Ω没有关系的常数a ,称为系统 H(z)具有严格线性相位。 由于严格线性相位条件在数学层面上处理起来较为困难,因此在 FIR 滤波器设计中一般使用广义线性相位。
如果一个离散系统的频率响应 H 可以表示为:
系统具有线性相位的充要条件:
当h[k]满足h[k]=h[M-k],称 h[k]偶对称。当h[k]满足 h[k]=-h[M-k],称 h[k]奇对称。按阶数 h[k]又可分为 M 奇数和 M 偶数,所以线性相位的 FIR 滤波器可以有四种类型。具体如下表所示:
4.IIR与FIR数字滤波器的比较
(1)IIR 滤波器 h(n)无限长,FIR 滤波器 h(n)有限长。
(2)在技术指标相同的条件下, IIR 滤波器的输出对输入有反馈,所以可以用比FIR 少的阶数来满足要求,存储单元少,运算次数也少,经济实惠。
(3)FIR 滤波器的相位是严格线性的,IIR 滤波器做不到这一点, IIR 滤波器的选择性越好,其相位的非线性越严重。
(4)FIR 滤波器主要采用非递归结构,有限精度的运算误差很小。而 IIR 滤波器在运算中会产生寄生振荡。
(5)FIR 滤波器可以使用快速傅里叶变换算法,而 IIR 滤波器不能这样。
(6)IIR 滤波器可以利用模拟滤波器的公式、数据和表格,计算量小。 FIR 滤波器设计时往往要借助计算机。
(7)IIR 滤波器极点位于 z 平面任意位置,而 FIR 滤波器极点固定在原点。
(8)IIR 滤波器用于设计规范化的选频滤波器, FIR 滤波器可设计各种幅度特性和相频特性的滤波器。 -
allsorts:在Rust中实现的字体解析器,整形引擎和子集-源码
2021-02-05 15:20:18它是从提取的, 是一个工具,用于对HTML和CSS文档进行排版和布局为PDF。 Allsorts整形引擎是与一起开发的,旨在指定OpenType字体的整形行为。 产品特点 解析TrueType( ttf ),OpenType( otf ),WOFF和WOFF2... -
python学习之旅(5)①for循环②for循环后接操作③使用range()④使用range()创建数字列表⑤对数字列表进行...
2020-12-30 04:25:334): (不包含最右端数值)print(name)得123④使用range()创建数字列表numbers=list(range(10)) (左端无数字默认从零开始...print('thanks to you')得
Abd is good
Cba is good
Bac is good
thanks to you
③使用函数range()
for name in range(1,4): (不包含最右端数值)
print(name)得
1
2
3
④使用range()创建数字列表
numbers=list(range(10)) (左端无数字默认从零开始)
print(numbers)得
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
numbers=list(range(1,6))
print(numbers)得
[1, 2, 3, 4, 5]
numbers=list(range(1,6,2)) (每次加2直到到达或超过右端数值)
print(numbers)得
[1, 3, 5]
numbers=[ ]
for number in range(1,11):
numbers.append(number**3)
print(numbers) 得
[1, 8, 27, 64, 125, 216, 343, 512, 729, 1000]
⑤对数字列表进行简单的统计计算
numbers=[1, 2,3,4,5]
min(numbers)得1
max(numbers)得5
sum(numbers)得15
⑥列表解析
numbers=[number**2 for number in range(1,5)] (“number**2”为表达式,“for number in range(1,5)”用于给表达式提供值)
print(numbers)得
[1, 4, 9, 16]
⑦切片
names=['abd','cba','bac']
print(names[0:3])得['abd', 'cba', 'bac']
print(names[0:])得['abd', 'cba', 'bac'] (没有指定终止索引则到列表末结束)
print(names[:2])得['abd', 'cba'] (没有指定起始索引则从列表头开始)
print(names[-2:])得['cba', 'bac']
⑧遍历切片
names=['abd','cba','bac']
for name in names[0:2]:
print(name.title())得
Abd
Cba
⑨复制列表
my_names=['abd','cba','bac']
your_names=my_names[0:2]
print(my_names)
print(your_names)得
['abd', 'cba', 'bac']
['abd', 'cba']
-
Android ListView从网络获取图片及文字显示
2012-11-27 11:05:05上一篇文章说的是ListView展示本地的图片...我们先从网上获取xml,然后对其进行解析,最后显示在ListView上。具体步骤: 客户端发出请求,获取xml客户端异步解析xmlListView将解析完的数据显示 一、Android客户端 -
DNS域名解析服务(正向解析,反向解析,主从解析)
2020-07-12 21:25:53文章目录DNS域名解析DNS系统的作用及类型DNS系统的作用DNS类型BIND的安装文件配置文件named.conf主配置文件named.rfc1912.zones区域配置文件named.localhost区域数据配置文件对配置文件进行语法检查正向解析正向解析... -
json解析之身份证解析
2018-12-01 11:28:09问题:在小程序开发中,从...原因:js解析json把身份证号作为一串数字解析,数字长度越界,因此自动对身份证号进行了处理。 解决:对获取到的身份证号前面或后面加一个字符或字符串,解析完成之后在去掉字符串。... -
有一个小白程序员,写了一个只能对5个数字进行排序的函数,现在有25个不重复的数字,
2018-09-23 14:16:44题目:有一个小白程序员,写了一个只能对5个数字进行排序的函数,现在有25个不重复的数字,请问小白同学最少调用几次该函数,可以找出其中最大的三个数? A.5 B.6 C.7 D.8 答案:C 解析:第一步:25人分为5组调用,... -
js中字符串解析成数字 parseInt("08")
2014-03-26 19:38:51js从字符串中解析成数字 问题 在对时间处理时,我们得到了好的编程者得到了“08”,“09”月份,为了日期的初始化或着比较月份的大小,匆匆进行 parseInt("08"); parseInt("09"); 一般我们都认为万事大吉了... -
awk从基础到高级之解析
2015-01-17 20:57:16awk简介awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大。简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析... -
FeignClient源码深度解析
2019-02-27 14:53:49springCloud feign主要对netflix feign进行了增强和包装,本篇从源码角度带你过一遍装配流程,揭开feign底层的神秘面纱。 主要包括feign整合ribbon,hystrix,sleuth,以及生成的代理类最终注入到spring容器的过程。... -
下划线间隔数字 排序_面试必备:经典算法动画解析之希尔排序
2020-11-23 07:45:29哈喽,我是程序员大鹏。前面我们介绍了冒泡排序、选择排序...插入排序思想插入排序是一种从序列左端开始依次对数据进行排序的算法。在排序过程中,索引左侧的数据陆续归位,而右侧留下的就是还没有被排序的数据。插... -
程序基本算法习题解析 最小的因子对差 :求出数字c的两个因子a和b(b>=a),使得a*b=c且使b-a值尽量小
2018-12-25 16:28:18要求两个大小最接近的因子a,b,可先求出c的平方根(非完全平方数时,向上取整),然后从近似平方根开始到1进行遍历,找到第一个能整除的数,即为a,c/a即为b。 代码如下: // Chapter11_2.cpp : Defines the ... -
重新赋值_图的十字链表存储方式解析之三:重新设计的十字双向链表
2020-12-29 09:17:14从上两篇文章中,看出图的十字链表存储优点很多,但删除边的操作相对复杂一些,这篇文章主要通过重新设计边结点,将单链表拓展为双向链表,从而对代码进行优化。首先,顶点结点结构不变。将边结点拓展为双向链表结点... -
DockerFile解析——DockerFile构建过程解析
2019-07-08 14:54:094、每条指令都会创建一个新的镜像层,并对镜像进行提交 二、Docker执行Dockerfile的大致流程 1、docker从基础镜像运行一个容器 2、执行一条指令并对容器作出修改 3、执行类似docker commit的操作提交一个新的... -
浏览器加载解析渲染机制的全面解析
2018-03-22 03:04:09(注1:如果有问题欢迎留言探讨,一起学习!本文首发于我的简书,转载请...这篇文章,将对浏览器的加载解析渲染机制进行深入地剖析。在这篇文章的写作过程中,我参考了网上大量相关资料,发现有不少文章只有文字,却... -
DockerFile 简介解析
2020-05-25 11:39:56一、是什么 1、DOckerFile是用来构建docker镜像的构建文件,是由一系列命令和参数构成的脚本 2、构建三步骤:编写DockerFile...④ 每条指令都会去创建一个新的镜像层,并对镜像进行提交 2、docker执行DockerFil.. -
ListView从网络获取图片及文字显示
2013-10-17 15:53:48上一篇文章说的是ListView展示...我们先从网上获取xml,然后对其进行解析,最后显示在ListView上。具体步骤: 客户端发出请求,获取xml客户端异步解析xmlListView将解析完的数据显示 一、Android客户端
-
MySQL Router 实现高可用、负载均衡、读写分离
-
物联网配电室环境远程监控运维系统解决方案
-
增强用户体验让网站和APP更具动感的几点建议
-
PHP base64 编码转化图片并进行指定路径的保存和上传处理
-
使用 Linux 平台充当 Router 路由器
-
javascript——判断数组中是否包含某元素
-
松翰单片机SN8P2711B移动电源控制板ALTIUM设计硬件原理图+PCB+软件程序文件.zip
-
spark大数据分析与实战
-
IRACC空调485NET调试软件180819.exe
-
Bansbach MAHA 17 1251 Z2Z2B82-120-360-004 350N气弹簧
-
Unity 热更新技术-ILRuntime
-
echarts折线图个性化填充、线条、拐点样式以及hover样式
-
Galera 高可用 MySQL 集群(PXC v5.6 + Ngin
-
MTK9632_9652_Toolbox_watchprops.rar
-
【硬核】一线Python程序员实战经验分享(1)
-
Cyberpunk2077地图数据分享
-
tp5微信小程序支付封装类库
-
【源码】基于Simscape的挖土机模型
-
NFS 实现高可用(DRBD + heartbeat)
-
基于无味卡尔曼滤波器的用于AUV的基于MEMS的低成本SINS的动态初始对准