前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >命令行二维码

命令行二维码

作者头像
ayqy贾杰
发布2023-03-15 18:46:38
2540
发布2023-03-15 18:46:38
举报
文章被收录于专栏:黯羽轻扬黯羽轻扬

感谢支持ayqy个人订阅号,每周义务推送1篇(only unique one)原创精品博文,话题包括但不限于前端、Node、Android、数学(WebGL)、语文(课外书读后感)、英语(文档翻译) 如果觉得弱水三千,一瓢太少,可以去 http://blog.ayqy.net 看个痛快

写在前面

发现一个有趣的东西,能在命令行显示二维码。日常一直是:

代码语言:javascript
复制
命令行起个sync服务
编辑器码码码,浏览器看看看
...码到差不多了
浏览器插件生成个二维码
掏出100个手机扫啊测啊
...咦,有问题
改改没好,场景比较复杂,得抽出来定位
复制个test文件
再生成个二维码,再扫再测,o了
...额,又发现个问题
...

浏览器二维码插件差不多能满足需求,在IDE、浏览器、终端、Finder之间频繁切换,虽然有点麻烦,但没有发现更好的办法……直到看见命令行二维码,怎么可以这么机智

一.原理

看到“命令行二维码”,想也知道原理是什么:输出到屏幕时可以控制前景色、背景色、文本样式

要输出二维码,只要能改背景色就够了,用白空格黑空格就能拼出来

例如:

代码语言:javascript
复制
# 输出focus here
# focus黑底白字,空格默认,here蓝底白字加粗
echo "\e[40;0;37mfocus\e[0m \e[44;1;37mhere\e[0m"

\e[0m重置为默认样式,一般控制序列格式为:

代码语言:javascript
复制
# \e[开头,m结尾
# 分号隔开的3个值分别是背景色、文本样式和前景色
\e[40;0;37m

支持的值如下:

代码语言:javascript
复制
# 文本样式
0: 常规文本
1: 加粗文本
4: 下划线文本# 前景色30-37
30: 黑色
31: 红色
32: 绿色
33: 黄色
34: 蓝色
35: 紫色
36: 青色
37: 白色# 背景色40-47
40: 黑色
41: 红色
42: 绿色
43: 黄色
44: 蓝色
45: 紫色
46: 青色
47: 白色

此外还有一些更强大的,比如移动光标、删除某行、清空屏幕等等,例如字符进度指示器:

代码语言:javascript
复制
echo -n '-'
arr=('\\' '|' '/' '-' '|' '100%')
for c in ${arr[@]};
do
   # 等1秒
   sleep 1
   # 左移一格,输出字符
   echo -en "\033[1D$c"
done

二.具体实现

1.生成二维码元数据

根据输入的字符串,按照二维码规则计算出二值矩阵

这个过程手动实现起来比较费劲,因为二维码是一个有几百项专利的技术,见http://www.qrcode.com/en/patent.html,需要买(弄)个ISO Specification实现一遍:

Obtaining QR Code Specification QR Code is established as an ISO (ISO/IEC18004) standard. QR Code specification can, therefore, be purchased from this organization. Purchasing ISO Standards Please search by inputting ISO No.18004 or X0510 to “Search and ISO Catalogue”. http://www.iso.ch/iso/en/prods-services/ISOstore/store.html

不过不用那么费劲,因为有开源版本,且有各种语言实现:https://github.com/kazuhikoarase/qrcode-generator

但还是有必要了解一些概念:

  • 尺寸(spec里叫Version,上面的开源版实现里叫TypeNumber) 值为1401对应最小矩阵21x2140对应最大的177x177
  • 定位图案 最明显的是二维码角角的3个回形框,3个点确定一个矩形。其它位置也有用来定位的图案
  • 纠错级别 有'L', 'M', 'Q', 'H'4个纠错级别,级别越高,容错率约高,携带的纠错数据也越多,所以才有个性化二维码
  • 数据类型 保留数据(格式信息,版本信息,定位图案信息),实际数据信息和纠错数据

2.输出

上面提到的qrcode-generator主要js api如下:

代码语言:javascript
复制
// 创建实例
qrcode(typeNumber, errorCorrectionLevel) => QRCode
// 传入待编码串
addData(data, mode) => void// 计算矩阵
make() => void// 获取结果矩阵行列数(列数等于行数)
getModuleCount() => number
// 获取矩阵单元值
isDark(row, col) => boolean

元数据有了,遍历矩阵拼接黑白空格字符串,输出:

代码语言:javascript
复制
// 黑白空格
var black = "\033[40m  \033[0m",
   white = "\033[47m  \033[0m",
   toCell = function (isBlack) {
       return isBlack ? black : white;
   },
   repeat = function (color) {
       return {
           times: function (count) {
               return new Array(count).join(color);
           }
       };
   },
   fill = function(length, value) {
       var arr = new Array(length);
       for (var i = 0; i < length; i++) {
           arr[i] = value;
       }
       return arr;
   };//...略去创建实例和计算矩阵部分// 遍历
var border = repeat(white).times(qrcode.getModuleCount() + 3);
output += border + '\n';
qrcode.modules.forEach(function (row) {
   output += white;
   output += row.map(toCell).join('');
   output += white + '\n';
});
output += border;// 输出
console.log(output);

然后就能在命令行显示一个大大的二维码了,如图:

terminal-qrcode

3.命令行优化

但是,在命令行显示的话,尺寸太大

二维码最小尺寸也是21x21,黑框里21行几乎占满默认一屏了,码稍长一点就显示不全了,而一般url码都超过21行,例如:

代码语言:javascript
复制
// 在纠错级别为M(默认)时
// 21行的二维码只能显示14个字符
https://www.ay
// 22行的只能显示26个字符
https://www.ayqy.net/blog/
//...

所以要想办法让输出的二维码行列尺寸小一点,最容易想到的就是用奇怪的Unicode字符拼:

unicode-block

再把列空格数量减半,这样宽高尺寸就都能缩小一半,如图:

terminal-qrcode-small

虽然丑一点,但仍然是可用的。那么还能不能更小,如果想缩小两半呢?

用同样的方法做不到,因为Unicode字符只有“下四分之一方块”、“下四分之三方块”和“左四分之三方块”、“左四分之一方块”,不够用了

三.开源npm包

很巧的是,上面提到的所有事情都有人做了:qrcode-terminal-alpha

把命令行二维码添进工作流工具里,构建完毕直接显示二维码,扫码会方便不少

参考资料

  • QR Code Generator:在线二维码生成器
  • kazuhikoarase/qrcode-generator:js api
  • 二维码的生成细节和原理
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-02-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 前端问问 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.原理
  • 二.具体实现
    • 1.生成二维码元数据
      • 2.输出
        • 3.命令行优化
        • 三.开源npm包
          • 参考资料
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档