1.vscode配置c/c++环境
2.QR CODE 的编码和解码的原理是怎样的,,要进行怎样的图像处理?
3.qr code是什么?
4.什么是三维码?
vscode配置c/c++环境
区分编辑器、编译器、IDE: 作者:C语言教学 编辑器就是处理文本(源码)的程序,写代码写的传奇免费列表源码就是文本,编辑器可能提供智能提示、代码高亮等辅助功能,但不负责源码到二进制文件的操作; 编译器就是负责将源码文本翻译成计算机能够理解和执行的二进制文件的程序; 集成开发环境(IDE,Integrated Development Environment )是用于提供程序开发环境的应用程序,包括了代码编辑器、编译器、调试器和图形用户界面工具。集成了代码编写、分析、编译、调试等一整套工具链。 什么是搭建环境: vscode定位代码编辑器,不是IDE,不包含编译功能,因此需要我们自己安装编译器、调试器等编译器套件,并使两者有效的配合起来,以实现快捷操作。把这一整套工具链整合到一起的过程就是我们所说的搭建环境。 ok,到这里,我们就清楚要做什么了:获取编辑器 -> 获取编译套装(编译器、调试器、头文件库等) -> 做好两者之间的沟通工作(配置文件) 两个东西:编辑器和编译套装 编辑器: VSCode 编译套装:win:mingw-w安装教程 下载 选项 重启 完全卸载 如果大家之前有安装过VSCode,然后只是简单卸载的话,再次安装之后,是还出现之前的配置信息,包括打开的文件夹、安装过的扩展等,这是因为之前并没有完全将VSCode卸载干净。如果想干净卸载掉VSCode再重新安装的话,就需要在卸载之后再删除掉两个目录的内容。分别是: C:\Users$用户名.vscode C:\Users$用户名\AppData\Roaming\Code 安装C/C++必备的插件 C/C++ 安装C/C++ Project Generator 示例一 在vscode中 ctrl+shift+p 打开菜单,在其中输入 create c 这时会弹出一个窗口,让你选中将源码放到哪个工作空间上,这个我选择C_Mutile,此时它会显式 这两个东西是啥呢? 先了解几个概念: 命令行:命令行 或 命令行界面,是一种基于文本的用来查看、处理、和操作计算机上的文件和程序的工具。 终端/控制台:可以输入命令行并显示程序运行过程中的信息以及程序运行结果的窗口。 不必要严格区分这两者的差别。 shell:终端自身并不执行用户输入的命令,它只是负责把输入的内容传送到主机系统,并把主机系统返回的结果呈现给用户。负责解释执行用户输入的命令并返回结果的,正是Shell,它是沟通用户和系统内核的中间桥梁。 我们写完代码之后,可以通过命令行去编译运行: 打开一个cmd终端 进入文件夹位置,然后gcc -o hello hello.c 但是每次都用命令行太麻烦了,怎么样才能更快捷呢?可以通过.vscode文件夹下的json配置文件来配置实现。这些json文件怎么写是由vscode开发团队规定的(感兴趣可以去看官方的文档), task是任务的意思,我们的编译和运行就是我们想要vscode执行的任务,为此我们要在tasks.json里写两个task:Build和Run(这里为什么不是Compile呢?是因为从源码到可执行的过程中不仅是编译(Compile),还有预编译、链接等过程,用构建(Build)来表述更合适)。除了编译和运行,我们还需要进行调试(Debug),这个就不是通过task来实现的了,而是通过launch.json文件来实现。 运行 方法一:按F5调试运行 方法二,图形界面 遇到的错误 g++ : 无法将“g++”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果包括路径,请确保路径正确,然后再试一次。 解决: 将MinGW配置到环境变量中,注意配置完之后要重启vscode 检查MinGW是否配置好: gcc --version g++ --version gdb --version 终端启动VSCode 打开一个终端,然后运行code命令即可启动终端。 运行code --help可以打印出VS Code命令行支持的所有参数 打开一个文件夹 在一个新窗口中打开这个文件或文件夹: code 文件夹/文件名 在一个已经打开的窗口来打开文件: code -r 文件夹/文件名 比较两个文件的内容 比较两个文件的内容: code -d 文件a 文件b。 比如:code -r -d a.txt b.txt 其他 VS Code 命令行除了支持打开磁盘上的源码j文件以外,也接受来自管道中的数据。这样你就可以将原本在命令行中展示的内容,实时地展示在 VS Code 里,然后在编辑器中搜索和修改。比如,你可以把当前目录下所有的文件名都展示在编辑器里,此时只需使用ls | code -命令。 关闭当前项目 file → close Folder 从资源管理器里调出系统终端 打开和创建一个集成终端: 打开终端的方法: 菜单栏:View–>Terminal 快捷键:Ctrl + `,按一下打开,再按一下关闭 命令面板:搜索并执行“切换集成终端”(Toggle Integrated Terminal) 具体效果: 如果还没有任何集成终端存在,那么它将创建一个新的,然后显示出来; 如果已经有几个集成终端了,那么就把终端面板调出来; 如果我们的光标就在集成终端里,那么这个命令会将终端面板隐藏。 若我们希望创建出一个新的终端来,而不是切换终端: 快捷键:Ctrl + Shift + ` 命令面板:搜索并执行 “新建集成终端”(Create New Intergrated Terminal) 如果我们的电脑屏幕足够大,或者我们希望在同一界面上看到多个运行的脚本,我们也可以把一个终端面板进行切分。我们只需按下 Cmd + \ 或者运行 “拆分终端”(Split Terminal),就能够将当前的终端一分为二;如果再次按下这个快捷键,就能够将当前的面板平均分为三份…… 最上面一行是状态栏: 侧边栏:在默认设置下 VS Code 的左侧侧边栏有五个组件,它们分别是: 资源管理器,主要用于浏览和管理文件和文件夹。 跨文件搜索,用于在当前文件夹内进行跨文件的搜索。 源代码管理,用于对当前文件夹下的代码进行版本管理,默认 VS Code 支持的版本管理软件是 Git。 启动和调试,用于对当前文件夹下的项目进行运行和调试。 插件管理,用于下载和管理 VS Code 里的插件。 在侧边栏的最下角还有一个齿轮形状的按钮 它提供了一些 VS Code 系统管理常用的快捷键,点击打开后,你可以看到命令面板、设置、键盘快捷方式、管理扩展等等一系列快速入口。 界面的最下面一行则是状态栏: 这个组件的作用就是将当前文件夹、编辑器状态、代码版本、代码错误等的简略讯息呈现给你。除此之外,很多插件也会选择将信息呈现在状态栏上。 面板(Panel) 不过“界面概览”并没有覆盖所有的组件,其中一个非常重要的部分就是面板(Panel),你可以在命令面板中执行“切换面板”命令来打开它。 打开后,你会看到面板的四个组件:问题面板、输出面板、调试控制台和终端。 问题面板(Problems Panel)的作用是展示当前文件夹下代码里的所有问题和警告,比如你的代码有语法错误、格式问题、拼写错误等 输出面板(Output Panel)的作用就是将核心命令和插件的运行状态和结果输出来,比如你使用 Git 来管理你的代码版本,你的每个 UI 上的版本操作,你都能在输出面板里看到这个操作对应的 Git 命令行以及它的运行结果。这样即使意外发生了, VS Code 无法完成指定的 Git 命令,你依然可以通过阅读输出面板找到问题所在,然后自行修复。 调试控制台主要是在调试代码时使用 终端是开发工作中不可或缺的一个工具,VS Code 则更进一步,把终端直接集成了进来。集成终端的存在,使得 VS Code 保持轻量级成为了可能性。 命令面板 设计目的:是 VS Code 快捷键的主要交互界面,这样不用鼠标,使得所有的操作都可以通过键盘进行 如何打开:Ctrl + Shift + P 打开之后,命令面板的输入框里已经有一个字符: 如果第一个字符是>(默认) ,当你继续输入字符时,VS Code 就会在所有命令里进行搜索。 VS Code 的绝大多数命令都可以在命令面板里搜到 所以熟练使用命令面板,你就可以摆脱鼠标,完全通过键盘操作来完成全部编码工作。 如果第一个字符是@,那么就扫描当前文件,提供所有的资金指标公式源码符号。) 如果第一个字符是?,就可以看到十几条选项,分别代表着你能在命令面板里使用的不同的功能 >(大于号) ,用于显示所有的命令。 @ ,用于显示和跳转文件中的“符号”(Symbols),在@符号后添加冒号:则可以把符号们按类别归类。 # 号,用于显示和跳转工作区中的“符号”(Symbols) :(冒号), 用于跳转到当前文件中的某一行。 如果输入框里没有任何的字符时,命令面板提供的功能是访问最近使用的文件 edt 是 edit(编辑)的缩写,输入 edt 和一个空格,命令面板就会显示所有已经打开的文件;而edt active则只会显示当前活动组中的文件。 ext 是 extension(插件)的缩写,输入 ext 和一个空格,就可以进行插件的管理;ext install 则可以在命令面板中搜索和安装插件。 task和debug 分别对应于任务和调试功能。 term 是 terminal(终端)的缩写,你可以用这个命令来创建和管理终端实例。 view 则是用于打开 VS Code 的各个 UI 组件。 下面是一些常用命令的快捷键: Ctrl + P :文件跳转 Ctrl + Shift + Tab:在所有打开的文件中跳转 Ctrl + Shift + Tab:跳转到文件中的符号 Ctrl + G:跳转到文件中的某一行 如下图,在输入框中输入文号,就能列出所有可用的相关命令 键盘操作 自定义快捷键 打开键盘快捷方式:Ctrl+K ,Ctrl+S 搜索"select to bracket"(选择括号内所有内容),双击 按下”Cmd + Shift + ]”,回车 删除快捷键 在搜索框内搜索你使用的快捷键 通过右键选择删除该快捷键的绑定 针对单词的光标移动 一个字符一个字符的移动:方向键 一个单词一个单词的移动:Option(Windows 上是 Ctrl 键)和方向键 对于代码块的光标移动 if、for 语句会使用花括号将代码块包裹起来,可以在{ }始末快速跳转: Cmd + Shift + \(Windows 上是 Ctrl + Shift + \) 选中文本 把光标到单词开头之间的所有字符全部选中:Option(Windows 上是 Ctrl 键) + 左方向键+ Shift 键 将光标到第一行,或者最后一行之间的字符选中:Cmd、Shift 和上下方向键 操作一行代码 删除一行代码:“ Cmd + Shift + K ” (Windows 上是 “Ctrl + Shift + K”) 剪切一行代码:“ Cmd + x ” (Windows 上是 “Ctrl + x”) 在当前行的下面开始新一行:“Cmd + Enter” (Windows 上是 “Ctrl + Enter”) 在当前行的上面开始新一行:“Cmd + Shift + Enter” (Windows 上是 “Ctrl + Shift + Enter”) 撤销光标移动 撤销光标移动:“Cmd + U”(Windows 上是 “Ctrl + U”) 调整字符大小写 在命名面板里搜索:transf, 来变换字符的大小写。 代码格式化 前提:VS Code已经安装了相关插件。 对整个文档进行缩进: “Option + Shift + F” (Windows 上是 Alt + Shift + F) 对选中代码进行缩进:“Cmd + K Cmd + F” (Windows 上是 Ctrl + K Ctrl + F) 将代码注释掉: Cmd + / (Windows 上时 Ctrl + /) 代码缩进 打开命令面板(快捷键“Cmd + Shift + P”),搜索 “reind”,然后使用 “重新缩进行” 将整个文档的缩进进行调整,但更多时候,你只需要运行 “重新缩进选中行” 来调整部分选中代码行的缩进。 行排序 无论是你在写代码,还是写 Markdown,你都可以把代码行按照字母序进行重新排序。不过这个命令比较小众,VS Code 并没有给这个命令指定快捷键,你可以调出命令面板,然后搜索 “按升序排列行” 或者 “按降序排列行” 命令执行。 合并代码行 有的时候你可能会为了避免代码看起来过于冗余,就会把比较短小的几行代码合并到一行里面去。这时,你只需要按下 “ Ctrl + j ” (Windows 上未绑定快捷键,可以打开命令面板,搜索 ”合并行“)就可以了,而不需要不断地调整光标、删除换行符。 修改函数或者变量的名字 只需把光标放到函数或者变量名上,然后按下 F2,这样这个函数或者变量出现的地方就都会被修改。 把一段长代码抽取出来转成一个单独的函数 只需选中那段代码,点击**的灯泡图标,然后选择对应的重构操作即可 要注意的是,并不是每个语言服务都支持重构的操作。如果你选中一段代码后,但没有看到那个**的灯泡图标,那么也就是说你使用的这门语言可能还没有支持快速重构。 代码跳转 跳转到了 函数的定义处: 将鼠标移动到foo 上 然后按下 Cmd 键,这时候 foo下面出现了一个下划线。 然后当我们按下鼠标左键,就跳转到了 函数的定义处。 跳转到函数定义的位置:F 跳转到函数的实现的位置:“Cmd + F” (Windows 上是 Ctrl + F) 找到函数/类在哪里被引用 将光标移动到函数或者类上面 按下Shift+ F 文件跳转 按下 “Cmd + P” (Windows 上是 Ctrl + P)时,跳出一个搜索框。 搜索你想要的文件 打开 直接打开:“Enter” 键 一个新的编辑器窗口中打开: “Cmd + Enter ” (Windows 上是 Ctrl + Enter)组合键 行跳转 将光标快速地移动到某一行 按下 “Ctrl + g”,调出行输入框 这个输入框的第一个字符就是 “ : ”,在这之后输入数字 将光标快速移动的某个文件的某一行: 按下 “Cmd + P” 在搜索框输入: 文件名:指定行,比如 a.txt:3 在一个文件里的符号之间跳转 按下 “Cmd + Shift + O” (Windows 上是 Ctrl + Shift + O),就能够看到当前文件里的所有符号。 使用方向键,或者搜索,找到你想要的符号后,按下回车,就能够立刻跳转到那个符号的电子书源码位置。 输入框里有一个 “@”符号,这时,如果你输入 “:”,就可以将当前文件的所有符号,进行分类,这样搜索符号也就更加方便。 在多个文件里的符号之间跳转 “Cmd + T” (Windows 上是 Ctrl + T),搜索这些文件里的符号 面包屑 怎么打开面包屑功能:“打开设置”(Open Settings),搜索 “breadcrumbs.enabled”,找到后将它打开。 怎么用?从左到右,我们能够看到一层一层文件夹的名字,然后是当前文件名,最后则是光标所在的函数的名字。我们可以通过点击这个工具栏上的文字,然后进行文件夹、文件或者是函数的跳转。 ”Cmd +F”搜索,按下 Enter 键在搜索结果当中快速跳转 把光标放在编辑器当中 按下 “Cmd + F” (Windows 上是 Ctrl + F),就能够快速地调出搜索窗口 调出搜索窗口的时候,编辑器就会把当前光标所在位置的单词自动填充到搜索框中。与此同时,当前文件里和搜索关键词相同的单词都会被高亮出来。 我们可以在在搜索框中搜索,然后按下Enter 键在搜索结果当中快速跳转 打开命令面板,搜索“配置用户代码片段”(Configure User Snippets)并且执行 这时候我们会看到一个列表,让我们选择语言。我们选中JavaScript 选择完语言后,我们就能看到一个 JSON 文件被打开了,这个文件里的内容,现在都是被注释掉的。我们可以选中第七行到第十四行,按下 Cmd+ / 取消注释。 这个就是代码片段了。 它是一个 JSON 文件,它的根对象下面的所有子节点都是一个单独的代码片段,并能够被我们调用和插入编辑器。 这个代码片段对象的键(key)是这个代码片段的名字,我们在书写时只要保证这个名字跟当前文件里的其他代码片段不冲突就可以了。 下面例子中: 这个代码片段的名字叫做 Print to console 这个代码片段对象的值,也就是花括号里的代码,必须要包含 “prefix” 前缀和 “body” 内容这两个属性。 同时,这个值还可以包含 “description” 描述这个属性,但这个属性不是必须的。 “prefix” 的作用是,当我们在编辑器里打出跟 “prefix” 一样的字符时,我们就能在建议列表里看到这个代码片段的选项,然后我们按下 Tab 键,就能够将这个代码片段的 “body” 里面的内容插入到编辑器里。如果这个代码片段有 “description” 这个属性的话,那么我们还能够在建议列表的快速查看窗口里看到这段 “description”。 { "Print to console": { "prefix": "log", "body": [ "console.log('$1');", "$2" ], "description": "Log output to console" } } 此时,我们可以打开一个 JavaScript 文件(还以之前的一段代码为例),然后输入 log,你就能够在建议列表里看到 Print to console 这个建议。然后再按下回车或者 Tab 键,就能够将这个代码片段插入编辑器了。 设置颜色主题 (1)打开编辑器 windows/linux:file—>perferences----> color theme macOS:code —>perferences----> color theme (2)使用方向键上下移动,选择不同的主题预览 (3)选择一个颜色主题,按下enter键,马上生效 设置文件图标主题 (1)打开编辑器 windows/linux:file—>perferences----> File Icon theme macOS:code —>perferences---->File Icon theme (2)使用方向键上下移动,选择不同的主题预览 (3)选择一个颜色主题,按下enter键,马上生效 None:禁用文件图标 首先需要说明的是,VS Code 的各个功能,都是基于当前打开的文件或者文件夹的。该怎么去理解这个概念呢? 如果你使用过 IDE 的话, 你应该记得在第一次打开 IDE 的时候,它们往往需要你创建一个工程,这个工程会生成一个特殊的工程文件。这个工程文件记载了这个项目有哪些相关的文件、项目的配置、构建脚本等等。这个文件记录着 IDE 管理工程的元信息,开发团队也能够通过共享这个工程文件保证成员工作环境的一致性。但是工程文件对用户体验就不太友好了,比如说项目文件可能对 IDE 的版本有所要求,项目文件损坏了 IDE 读取不了但是贴吧源码我们也不知道如何修复,等等。 VS Code 则选择了一种相对轻量,而且大家都易于理解的方式,那就是所有的操作都基于文件和文件夹。当你打开一个文件夹,VS Code 的核心功能就会对这个文件夹进行分析,并提供对应的功能。比如,在打开的文件夹下检测到有 .git 文件,就加载 Git 插件来提供版本管理的功能;或者发现文件夹下有 tsconfig.json ,就会激活 TypeScript 插件提供语言服务。 当你打开一个文件夹之后,你就能在工作台的最左侧看到资源管理器。资源管理器将当前文件夹下的文件和子文件夹,以树形结构的形式呈现出来。每一个文件的前面还会有一个小图标,用于反映文件的类型。 在资源管理器的最上方,你可以看到一个列表,叫做 “打开的编辑器”。这个很好理解,就是指这里面列出的都是当前已经被打开的文件。QR CODE 的编码和解码的原理是怎样的,,要进行怎样的图像处理?
/blog/static//
一、什么是QR码
QR码属于矩阵式二维码中的一个种类,由DENSO(日本电装)公司开发,由JIS和ISO将其标准化。QR码的样子其实在很多场合已经能够被看到了,我这还是贴个图展示一下:
这个图如果被正确解码,应该看到我的名字和邮箱。
二、QR码的特点
说到QR码的特点,一是高速读取(QR就是取自“Quick Response”的首字母),对读取速度的体验源自于我手机上的一个软件,象上面贴出的码图,通过摄像头从拍摄到解码到显示内容也就三秒左右,对摄像的角度也没有什么要求;
二是高容量、高密度;理论上内容经过压缩处理后可以存个数字, 个字母和数字混合字符,个8位字节数据,个汉字;
三是支持纠错处理;纠错处理相对复杂,目前我还没有深入了解,按照QR码的标准文档说明,QR码的纠错分为4个级别,分别是:
level L : 最大 7% 的错误能够被纠正;
level M : 最大 % 的错误能够被纠正;
level Q : 最大 % 的错误能够被纠正;
level H : 最大 % 的错误能够被纠正;
四是结构化;看似无规则的图形,其实对区域有严格的定义,下图就是一个模式2、版本1的QR图结构(关于QR码的"模式"、"版本"将在后面进行介绍):
在上图*的矩阵中,黑白的区域在QR码规范中被指定为固定的位置,称为寻像图形(finder pattern) 和 定位图形(timing pattern)。寻像图形和定位图形用来帮助解码程序确定图形中具体符号的坐标。
**的区域用来保存被编码的数据内容以及纠错信息码。
蓝色的区域,用来标识纠错的级别(也就是Level L到Level H)和所谓的"Mask pattern",这个区域被称为“格式化信息”(format information)。
五是扩展能力。QR码的Structure Append特点,使一个QR码可以分解成多个QR码,反之,也可以将多个QR码的数据组合到一个QR码中来。
三、QR码的模式和版本
前面提到过QR码的模式(Model)和版本(Version)。QR码分为Model1和Model2两种模式,Model1是对QR的初始定义,Model2是对Model1的扩展,目前使用较为普遍的是Model2,本文的所有说明也仅用于Model2。
QR图的大小(size)被定义为版本(Version),版本号从1到。版本1就是一个*的矩阵,每增加一个版本号,矩阵的大小就增加4个模块(Module),因此,版本就是一个*的矩阵。(版本越高,意味着存储的内容越多,纠错能力也越强)。
三、QR码支持的编码内容
QR码支持编码的内容包括纯数字、数字和字符混合编码、8位字节码和包含汉字在内的多字节字符。其中:
数字:每三个为一组压缩成bit。
字母数字混合:每两个为一组,压缩成bit。
8bit字节数据:无压缩直接保存。
多字节字符:每一个字符被压缩成bit。
(编码)
编码就是把常见的数字、字符等转换成QR码的方法。说具体的编码之前,先说一下QR码的最大容量问题。
一、最大容量
QR码的最大容量取决于选择的版本、纠错级别和编码模式(Mode:数字、字符、多字节字符等)。以版本1、纠错级别为Level Q的QR码为例,可以存储个纯数字,或个字母数字混合字符或个8bit字节数据。如果要存储同样多的内容同时提高纠错级别,则需要采用更高的版本。版本1~9 数据容量、纠错码容量对照如下表:
(version)
(error correcting level)
(count of data code words)
count of EC code words
(numeric)
(alphanumeric)
8bit
1 L 7
M
Q
H 9 7
2 L
M
Q
H
3 L
M
Q
H
4 L
M
Q
H
5 L
M
Q
H
6 L
M
Q
H
7 L
M
Q
H
8 L
M
Q
H
9 L
M
Q
H
如果要了解更详细的QR码容量信息,可以到电装的网站去看看/qrcode/vertable1-e.html。
下面,就举例说明将“ABCDE”转换成为版本1、Level H的QR码转换方法。
二、模式标识符(Mode Indicator)
QR码的模式(Mode)就是前文提到的数字、字符、8bit 字节码、多字节码等。对于不同的模式,都有对应的模式标识符(Mode Indicator)来帮助解码程序进行匹配,模式标识符是4bit的二进制数:
1、数字模式(numeric mode ):
2、混合字符模式(alphanumeric mode) :
3、8bit byte mode:
4、日本汉字(KANJI mode) :
5、中国汉字(GB):
由于示例文本串是混合字符,因此将选择alphanumeric mode,其标识码为:
三、文本串计数标识符(Character count indicator)
文本串计数标识符用来存储源内容字符串的长度,在版本1-9的QR码中,文本串长度标识符自身的长度被定义为:
数字 : bit
混合字符 : 9bit
8bit 字节码 : 8bit
多字节码 : 8bit
在本例中,源文本串的长度为8个字符,混合字符的长度为9bit,因此将字符个数8编码为9位二进制表示:
加上混合字符模式标识码,总的编码为
四、数据内容编码
1、数字模式下的编码
在数字模式下,数据被限制为3个数字一段,分成若干段。如:"" 将分成"" 和 "",分别被编码成bit的二进制数。“”的bit二进制表示法为:,实际上就是二进制的。
当数据的长度不足3个数字时,如果只有1个数字则用4bit,如果有2个数字就用7个bit来表示。
如:""被分成""和"6"两段,因此被表示为" "。
2、混合字符模式下的编码
混合字符模式编码,其字符对照表如下:
0 0 A K U +
1 1 B L V -
2 2 C M W .
3 3 D N X /
4 4 E O Y :
5 5 F P Z
6 6 G Q [sp]
7 7 H R $
8 8 I S %
9 9 J T * 3
编码方式为:
源码被分成两个字符一段,如下所示,每段的第一个字符乘上,再用第二个数字相加。因此每段变成了bit的2进制码,如果字符个数只有1个,则用6bit表示。
示例:
"AB" "CD" "E1" ""
*+ *+ *+1 *2+3
3、8bit字节数据不经编码转换直接保存。
五、编码终止符(Terminator)
如果编码后的字符长度不足当前版本和纠错级别所存储的容量,则在后续补"",如果容量已满则无需添加终止符。此时得到的编码串为:
六、编成8bit码字(Code words)
将以上的编码再按8bit一组,形成码字(code words):
如果尾部数据不足8bit,则在尾部充0:
如果编码后的数据不足版本及纠错级别的最大容量,则在尾部补充 "" 和 "",直到全部填满。最后,版本1、Level H下的"ABCDE" 的QR码是:
十进制表示法为:
QR码编码原理三(日本汉字和中文编码)
一、日本汉字(KANJI)是两个字节表示的字符码,编码的方式是将其转换为字节的二进制码制。
转换步骤为:
1、对于JIS值为(hex) 到9FFC(hex)之间字符:
a)将待转换的JIS值减去(hex);
b)将高位字节乘以C0(hex);
c)将b)步骤生成的数据加上低位字节;
d)将结果转换为位二进制串。
2、对于JIS值为E(hex)到EBBF(hex)之间的字符:
a)将待转换的JIS值减去C(hex);
b)将高位字节乘以C0(hex);
c)将b)步骤生成的数据加上低位字节;
d)将结果转换为位二进制串。
二、中文汉字的与日文汉字转换步骤相似:
1、对于第一字节为0xA1~0xAA之间,第二字节在0xA1~0xFE之间字符:
a)第一字节减去0xA1;
b)上一步结果乘以0x;
c)第二字节减去0xA1;
d)将b)步骤的结果加上c步骤的结果;
e)将结果转换为位二进制串。
1、对于第一字节为0xB0~0xFA之间,第二字节在0xA1~0xFE之间字符:
a)第一字节减去0xA6;
b)上一步结果乘以0x;
c)第二字节减去0xA1;
d)将b)步骤的结果加上c步骤的结果;
e)将结果转换为位二进制串。
qr code是什么?
基础知识
首先,我们先说一下二维码一共有个尺寸。官方叫版本Version。Version 1是 x 的矩阵,Version 2是 x 的矩阵,Version 3是的尺寸,每增加一个version,就会增加4的尺寸,公式是:(V-1)*4 + (V是版本号) 最高Version ,(-1)*4+ = ,所以最高是 x 的正方形。
下面我们看看一个二维码的样例:
定位图案
Position Detection Pattern是定位图案,用于标记二维码的矩形大小。这三个定位图案有白边叫Separators for Postion Detection Patterns。之所以三个而不是四个意思就是三个就可以标识一个矩形了。
Timing Patterns也是用于定位的。原因是二维码有种尺寸,尺寸过大了后需要有根标准线,不然扫描的时候可能会扫歪了。
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位数字会被编成 ,,bits,编成多长还要看二维码的尺寸(下面有一个表Table 3说明了这点)
Alphanumeric mode 字符编码。包括 0-9,大写的A到Z(没有小写),以及符号$ % * + – . / : 包括空格。这些字符会映射成一个字符索引表。如下所示:(其中的SP是空格,Char是字符,Value是其索引值) 编码的过程是把字符两两分组,然后转成下表的进制,然后转成bits的二进制,如果最后有一个落单的,那就转成6bits的二进制。而编码模式和字符的个数需要根据不同的Version尺寸编成9, 或个二进制(如下表中Table 3)
Byte mode, 字节编码,可以是0-的ISO--1字符。有些二维码的扫描器可以自动检测是否是UTF-8的编码。
Kanji mode 这是日文编码,也是双字节编码。同样,也可以用于中文编码。日文和汉字的编码会减去一个值。如:在0X to 0X9FFC中的字符会减去,在0XE到0XEBBF中的字符要减去0XC,然后把结果前两个进制位拿出来乘以0XC0,然后再加上后两个进制位,最后转成bit的编码。如下图示例:
Extended Channel Interpretation (ECI) mode 主要用于特殊的字符集。并不是所有的扫描器都支持这种编码。
Structured Append mode 用于混合编码,也就是说,这个二维码中包含了多种编码格式。
FNC1 mode 这种编码方式主要是给一些特殊的工业或行业用的。比如GS1条形码之类的。
简单起见,后面三种不会在本文 中讨论。
下面两张表中,
Table 2 是各个编码格式的“编号”,这个东西要写在Format Information中。注:中文是
Table 3 表示了,不同版本(尺寸)的二维码,对于,数字,字符,字节和Kanji模式下,对于单个编码的2进制的位数。(在二维码的规格说明书中,有各种各样的编码规范表,后面还会提到)
下面我们看几个示例,
示例一:数字编码
在Version 1的尺寸下,纠错级别为H的情况下,编码:
1. 把上述数字分成三组:
2. 把他们转成二进制: 转成 ; 转成 ; 转成 。
3. 把这三个二进制串起来:
4. 把数字的个数转成二进制 (version 1-H是 bits ): 8个数字的二进制是
5. 把数字编码的标志和第4步的编码加到前面:
示例二:字符编码
在Version 1的尺寸下,纠错级别为H的情况下,编码: AC-
1. 从字符索引表中找到 AC- 这五个字条的索引 (,,,4,2)
2. 两两分组: (,) (,4) (2)
3.把每一组转成bits的二进制:
(,) *+ 等于 转成 (,4) *+4 等于 转成 (2) 等于 2 转成
4. 把这些二进制连接起来:
5. 把字符的个数转成二进制 (Version 1-H为9 bits ): 5个字符,5转成
6. 在头上加上编码标识 和第5步的个数编码:
结束符和补齐符
假如我们有个HELLO WORLD的字符串要编码,根据上面的示例二,我们可以得到下面的编码,
编码
字符数
HELLO WORLD的编码
我们还要加上结束符:
编码
字符数
HELLO WORLD的编码
结束
按8bits重排
如果所有的编码加起来不是8个倍数我们还要在后面加上足够的0,比如上面一共有个bits,所以,我们还要加上2个0,然后按8个bits分好组:
补齐码(Padding Bytes)
最后,如果如果还没有达到我们最大的bits数的限制,我们还要加一些补齐码(Padding Bytes),Padding Bytes就是重复下面的两个bytes: (这两个二进制转成十进制是和,我也不知道为什么,只知道Spec上是这么写的)关于每一个Version的每一种纠错级别的最大Bits限制,可以参看QR Code Spec的第页到页的Table-7一表。
假设我们需要编码的是Version 1的Q纠错级,那么,其最大需要个bits,而我们上面只有个bits,所以,还需要补个bits,也就是需要3个Padding Bytes,我们就添加三个,于是得到下面的编码:
上面的编码就是数据码了,叫Data Codewords,每一个8bits叫一个codeword,我们还要对这些数据码加上纠错信息。
纠错码
上面我们说到了一些纠错级别,Error Correction Code Level,二维码中有四种级别的纠错,这就是为什么二维码有残缺还能扫出来,也就是为什么有人在二维码的中心位置加入图标。
错误修正容量
L水平 7%的字码可被修正
M水平 %的字码可被修正
Q水平 %的字码可被修正
H水平 %的字码可被修正
那么,QR是怎么对数据码加上纠错码的?首先,我们需要对数据码进行分组,也就是分成不同的Block,然后对各个Block进行纠错编码,对于如何分组,我们可以查看QR Code Spec的第页到页的Table-到Table-的定义表。注意最后两列:
Number of Error Code Correction Blocks :需要分多少个块。
Error Correction Code Per Blocks:每一个块中的code个数,所谓的code的个数,也就是有多少个8bits的字节。
举个例子:上述的Version 5 + Q纠错级:需要4个Blocks(2个Blocks为一组,共两组),头一组的两个Blocks中各个bits数据 + 各 9个bits的纠错码(注:表中的codewords就是一个8bits的byte)(再注:最后一例中的(c, k, r )的公式为:c = k + 2 * r,因为后脚注解释了:纠错码的容量小于纠错码的一半)
下图给一个5-Q的示例(因为二进制写起来会让表格太大,所以,我都用了十进制,我们可以看到每一块的纠错码有个codewords,也就是个8bits的二进制数)
组
块
数据
对每个块的纠错码
1 1 6 6
2 7 7 6
2 1 7 6 7
2 6 5 2
注:二维码的纠错码主要是通过Reed-Solomon error correction(里德-所罗门纠错算法)来实现的。对于这个算法,对于我来说是相当的复杂,里面有很多的数学计算,比如:多项式除法,把1-的数映射成2的n次方(0<=n<=)的伽罗瓦域Galois Field之类的神一样的东西,以及基于这些基础的纠错数学公式,因为我的数据基础差,对于我来说太过复杂,所以我一时半会儿还有点没搞明白,还在学习中,所以,我在这里就不展开说这些东西了。还请大家见谅了。(当然,如果有朋友很明白,也繁请教教我)
最终编码
穿插放置
如果你以为我们可以开始画图,你就错了。二维码的混乱技术还没有玩完,它还要把数据码和纠错码的各个codewords交替放在一起。如何交替呢,规则如下:
对于数据码:把每个块的第一个codewords先拿出来按顺度排列好,然后再取第一块的第二个,如此类推。如:上述示例中的Data Codewords如下:
块 1 6 6
块 2 7 7 6
块 3 7 6 7
块 4 6
我们先取第一列的:, , ,
然后再取第二列的:, , , , ,, ,
如此类推:, , , , ,, , ……… ……… ,,6,,,7,
对于纠错码,也是一样:
块 1
块 2
块 3
块 4 5 2
和数据码取的一样,得到:,,,,,,,,…… …… ,,,
然后,再把这两组放在一起(纠错码放在数据码之后)得到:
, , , , , , , , , , , , , 7, , , , , , , , , 7, 6, , , , , , 7, , , , , , , , , , , 6, , , , , , 6, , 6, , , , , , , , , 6, , , 7, , , , , , , , , , , , , 5, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , 2, , , , , , , , , , , , , , , ,
这就是我们的数据区。
Remainder Bits
最后再加上Reminder Bits,对于某些Version的QR,上面的还不够长度,还要加上Remainder Bits,比如:上述的5Q版的二维码,还要加上7个bits,Remainder Bits加零就好了。关于哪些Version需要多少个Remainder bit,可以参看QR Code Spec的第页的Table-1的定义表。
画二维码图
Position Detection Pattern
首先,先把Position Detection图案画在三个角上。(无论Version如何,这个图案的尺寸就是这么大)
Alignment Pattern
然后,再把Alignment图案画上(无论Version如何,这个图案的尺寸就是这么大)
关于Alignment的位置,可以查看QR Code Spec的第页的Table-E.1的定义表(下表是不完全表格)
下图是根据上述表格中的Version8的一个例子(6,,)
Timing Pattern
接下来是Timing Pattern的线(这个不用多说了)
Format Information
再接下来是Formation Information,下图中的蓝色部分。
Format Information是一个个bits的信息,每一个bit的位置如下图所示:(注意图中的Dark Module,那是永远出现的)
这个bits中包括:
5个数据bits:其中,2个bits用于表示使用什么样的Error Correction Level, 3个bits表示使用什么样的Mask
个纠错bits。主要通过BCH Code来计算
然后个bits还要与做XOR操作。这样就保证不会因为我们选用了的纠错级别和的Mask,从而造成全部为白色,这会增加我们的扫描器的图像识别的困难。
下面是一个示例:
关于Error Correction Level如下表所示:
关于Mask图案如后面的Table 所示。
Version Information
再接下来是Version Information(版本7以后需要这个编码),下图中的蓝色部分。
Version Information一共是个bits,其中包括6个bits的版本号以及个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的纠错算法的库,或是看看别人的源代码是怎么实现这个繁锁的编码。
什么是三维码?
三维码是码与防伪标识的总概括,是一个连接器,是一个信息窗口,个性特征明显。完美兼容二维码特性又区别于印刷二维码,本身就具有防伪特性,在物理上是结构的、立体的、唯一的、不可复制的。三维码
三维码采用一种多层颜色结构材料,非市面上能买到的普通材料。用手触摸具有随机深浅凹感结构特征,非墨迹堆叠印刷。三维码既是一个信息窗口与载体,又将防伪特征与“码”真正结合在一起。
三维码不是防伪标识,它本身是一种码,在信息呈现时自然形成了防伪的功能与特征,做到了信息与防伪的真正融合。天鉴三维码自身的防伪功能不是有意生产出来的,是信息呈现时与生俱来的,是不可复制的。天鉴三维码巧妙地将信息解读和真伪验证的过程融为一体。给每一个产品都赋予一个天鉴三维码,相当于给每个产品都赋予了一个身份信息,同时也给每个产品都赋予了一个灵性的窗口,在展现同类产品的不同之处时,又通过信息的互联互通实现产品信息的数字化、信息化。