二维码图像编码原理(字符编码:ASCII、UTF-8)

编码原理

我们日常生活中通过扫描二维码可以获得相应信息,例如:扫描百度首页的二维码就可以进入到百度首页,百度首页二维码图像中存储的其实是字符信息——百度首页的地址:https://www.baidu.com
又因为计算机中数据都是通过二进制数编码存储的,所以字符信息可以看做是一串具有规则的1、0排列字符串。
假如对应字符的编码为(4bit位随便编排一种): w:0000 ,b:0001,a:0010,i:0011,.:0100,d:0101,u:0110 … …

 www.baidu.com
相应存储编码:0000 0000 0000 0100 0001 0010 0011 0101 0110... ...        
             w    w    w   .     b     a    i    d   u... ...

那么通过这些0、1字符串,将其按0代表白色方块,1代表黑色方块,按规律可视化成我们现在所看到的的二维码,通过工具扫描之后即可访问相应信息。

以上就是二维码的内涵所在,但是要真正按要求画出一个现在计算机可以识别成功的二维码图像还得遵循统一的字符编码要求和二维码图像的绘制要求,并不是想象中那么简单,现在所见的二维码是分了板块的,有固定的算法和功能模块。对于能识别出的二维码具体的绘制要求和算法,就不展开介绍了,感兴趣的读者可以自行了解。

字符编码

为什么要统一字符编码?

具体用哪些二进制数字表示哪个符号,当然每个人都可以约定自己的一套(这就叫编码),而大家如果要想互相通信而不造成混乱,那么大家就必须使用相同的编码规则。
计算机全世界的人都在用,每个国家的字符都是不一样的,但是不存在外国人写的代码中国人运行出来结果不同,或者是中国人在代码中写的汉字,在国外人运行出来出现乱码的情况。前提是使用同一个编码标准。
目前的文字编码标准主要有 ASCII、GB2312、GBK、Unicode等。ASCII 编码是最简单的西文编码方案GB2312、GBK、GB18030 是汉字字符编码方案的国家标准ISO/IEC 10646 和 Unicode 都是全球字符编码的国际标准

注:GBK编码中文占2个字节,英文占1个字节;
        UTF-8编码中文占3个字节,英文占1个字节

ANSI:

ANSI并不是某一种特定的字符编码,而是在不同的系统中,ANSI表示不同的编码——系统设置编码。你的美国同事Bob的系统中ANSI编码其实是ASCII编码(ASCII编码不能表示汉字,所以汉字为乱码),而你的系统中(“汉字”正常显示)ANSI编码其实是GBK编码,而韩文系统中(“한국어”正常显示)ANSI编码其实是EUC-KR编码。

常见字符编码

ASCII编码:

由于计算机是美国人发明的,因此,最早只有128个字母(0~127)被编码到计算机里,也就是大小写英文字母、数字和一些符号,这个编码表被称为ASCII编码,比如大写字母 A 的编码是65,小写字母 z 的编码是122。
  但是要处理中文显然一个字节是不够的,至少需要两个字节,而且还不能和ASCII编码冲突,所以,中国制定了GB2312编码,用来把中文编进去。
  全世界有上百种语言,日本把日文编到Shift_JIS里,韩国把韩文编到Euc-kr里,各国有各国的标准,就会不可避免地出现冲突,结果就是,在多语言混合的文本中,显示出来会有乱码。为此引入Unicode编码。
部分ASCII码展示:  在这里插入图片描述
  … …
在这里插入图片描述

统一码(Unicode)

Unicode 是为了解决传统的字符编码方案的局限而产生的,它为每种语言中的每个字符设定了统一并且唯一的二进制编码,以满足跨语言、跨平台进行文本转换、处理的要求。就是将世界上所有的文字用2个字节统一进行编码。那样,像这样统一编码,2个字节就已经足够容纳世界上所有的语言的大部分文字了。
现在用的是UCS-2,即2个字节编码,而UCS-4是为了防止将来2个字节不够用才开发的(非常偏僻的字符)。

ASCII编码是1个字节,而Unicode编码通常是2个字节,举例如下
字母 A 用ASCII编码是十进制的65,二进制的01000001;

字符 0 用ASCII编码是十进制的48,二进制的00110000,注意字符 ‘0’ 和整数 0 是不同的;

汉字 已经超出了ASCII编码的范围,用Unicode编码是十进制的20013,二进制的01001110 00101101。

如果把ASCII编码的 A 用Unicode编码,只需要在前面补0就可以,因此, A 的Unicode编码是00000000 01000001。
但是,可以发现 写的文本基本上全部是英文的话,用Unicode编码比ASCII编码需要多一倍的存储空间,在存储和传输上就十分不划算。为此可以改变一下Unicode的编码方案(下文介绍)。

部分Unicode编码:在这里插入图片描述
汉字在Unicode中的编码范围:
链接: 汉字编码详细查询.
在这里插入图片描述

UTF-8

UTF-8是针对Unicode的一种可变长度字符编码。它可以用来表示Unicode标准中的任何字符,而且其编码中的第一个字节仍与ASCII相容,使得原来处理ASCII字符的软件无须或只进行少部分修改后,便可继续使用。

Unicode只是确定了所有字符的编码数值,但是它并没有指定代码点如何在计算机上存储。 UCS4、UTF-8、UTF-16(UTF后的数字代表编码的最小单位,如UTF-8表示最小单位1字节(=8 bits),所以它可以使用1、2、3字节等进行编码存储,UTF-16表示最小单位2字节,所以它可以使用2、4字节进行编码)都是Unicode的编码方案。其中UTF-8因可以兼容ASCII而被广泛使用。
eg:UTF-8
当存储到英文字母 A 的时候,只分配一个字节8bit大小就足够了,于是存储01000001
当存储到中文 的时候,分配三个字节24bit大小空间存储,于是存储11100100 10111000 10101101
概括来讲就是按需分配编码位

UTF-8基本编码规则:1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
如下表所示:字母x表示可用编码的位。

Unicode符号范围 | UTF-8编码方式
(十六进制) | (二进制)
0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx (可填11位unicode码)
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx (可填16位unicode码)
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx (可填21位unicode码)

以“中”(01001110 00101101)为例,依上表可知“二”在UTF-8编码中为三个字节
使用格式1110xxxx 10xxxxxx 10xxxxxx,从最后一个二进制位开始,依次从后向前填入格式中的x,多出的位补0。这样就得到了
11100100 10111000 10101101 加黑字体顺序连接就为Unicode编码

Java实现简易二维码

由于UTF-8编码规则较为复杂,将其简化:对于英文,分配8bit,采用Unicode编码,不够8bit,补0;对于中文,分配3字节24bit位,第一个字节全为1,表示向后获取2个字节的真实数据,后两个字节是按照Unicode编码。

重要数据结构:

//生成二维码
//将String转为char,再转为二进制字符串
char c=text.charAt(i);
cbinary=Integer.toBinaryString(c);	//将c变为二进制字符串
toBinaryString()形参本来为int型,char传入发生自动转型,获得char的十进制数


//解析二维码图片获得文字信息
int rgb=buff.getRGB(m, j);
if(rgb==Color.white.getRGB())
   rebinarytext=rebinarytext+"0";
else
   rebinarytext=rebinarytext+"1";   
   //将字符串rebinarytext按照二进制转为十进制整型数
   Integer.parseInt(rebinarytext, 2)
   //强制转型整型为char,获得字符串
   retext=retext+(char)Integer.parseInt(rebinarytext, 2);

实现效果

二维码生成器 2021-07-26 12-39-18

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:像素格子 设计师:CSDN官方博客 返回首页

打赏作者

GuochaoHN

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值