본문으로 건너뛰기

명령줄 QR 코드

무료2017-02-05#Tool#终端输出二维码#命令行显示二维码#terminal qrcode#二维码生成算法#qrcode spec

생산성을 높이는 과정에서 필요한 것은 약간의 상상력일지도 모릅니다.

들어가며

명령줄에서 QR 코드를 표시할 수 있는 흥미로운 것을 발견했습니다. 일상적인 워크플로우는 이랬습니다:

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

브라우저 QR 코드 플러그인으로도 어느 정도 수요는 충족되지만, IDE, 브라우저, 터미널, Finder 사이를 빈번하게 오가는 것이 조금 번거로웠습니다. 하지만 더 나은 방법을 찾지 못하고 있었죠... 명령줄 QR 코드를 보기 전까지는요. 어쩜 이렇게 기발할 수 있을까요?

1. 원리

'명령줄 QR 코드'를 보자마자 원리가 무엇인지 짐작이 갔습니다. 화면에 출력할 때 전경색, 배경색, 텍스트 스타일을 제어할 수 있다는 점이죠.

QR 코드를 출력하려면 배경색만 바꿀 수 있으면 충분합니다. 흰색 공백과 검은색 공백을 조합해서 만들 수 있습니다.

예를 들어:

# 输出focus here
# focus黑底白字,空格默认,here蓝底白字加粗
echo "\e[40;0;37mfocus\e[0m \e[44;1;37mhere\e[0m"

\e[0m은 기본 스타일로 재설정하며, 일반적인 제어 시퀀스 형식은 다음과 같습니다:

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

지원되는 값은 다음과 같습니다:

# 文本样式
0: 常规文本
1: 加粗文本
4: 下划线文本

# 前景色30-37
30: 黑色
31: 红色
32: 绿色
33: 黄色
34: 蓝色
35: 紫色
36: 青色
37: 白色

# 背景色40-47
40: 黑色
41: 红色
42: 绿色
43: 黄色
44: 蓝色
45: 紫色
46: 青色
47: 白色

이 외에도 커서 이동, 특정 행 삭제, 화면 지우기 등 더 강력한 기능들이 있습니다. 예를 들어 문자 기반 진행 표시기입니다:

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

2. 구체적인 구현

1. QR 코드 메타데이터 생성

입력된 문자열을 기반으로 QR 코드 규칙에 따라 이진 행렬을 계산합니다.

이 과정을 수동으로 구현하는 것은 꽤 까다롭습니다. QR 코드는 수백 개의 특허가 걸린 기술이기 때문입니다 (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

그래도 몇 가지 개념은 알아둘 필요가 있습니다:

  • 크기 (사양서에서는 Version, 위 오픈 소스 구현에서는 TypeNumber라고 부름)

    값은 1에서 40까지이며, 1은 최소 행렬인 21x21, 40은 최대인 177x177에 해당합니다.

  • 위치 찾기 패턴

    가장 눈에 띄는 것은 QR 코드 모서리의 사각형 상자 3개로, 세 점이 하나의 직사각형을 결정합니다. 다른 위치에도 위치 파악을 위한 패턴이 있습니다.

  • 오류 수정 레벨

    'L', 'M', 'Q', 'H'의 4가지 오류 수정 레벨이 있습니다. 레벨이 높을수록 내결함성이 높아지고 포함되는 오류 수정 데이터도 많아집니다. 그래서 개성 있는 QR 코드를 만들 수 있는 것이죠.

  • 데이터 유형

    예약 데이터(형식 정보, 버전 정보, 위치 찾기 패턴 정보), 실제 데이터 정보 및 오류 수정 데이터.

2. 출력

앞서 언급한 qrcode-generator의 주요 JS API는 다음과 같습니다:

// 创建实例
qrcode(typeNumber, errorCorrectionLevel) => QRCode
// 传入待编码串
addData(data, mode) => void

// 计算矩阵
make() => void

// 获取结果矩阵行列数(列数等于行数)
getModuleCount() => number
// 获取矩阵单元值
isDark(row, col) => boolean

메타데이터가 준비되었으니 행렬을 순회하며 흑백 공백 문자열을 이어 붙여 출력합니다:

// 黑白空格
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);

그러면 명령줄에 커다란 QR 코드가 표시됩니다. 그림과 같이:

[caption id="attachment_1323" align="alignnone" width="625"]terminal-qrcode terminal-qrcode[/caption]

3. 명령줄 최적화

하지만 명령줄에 표시하기에는 크기가 너무 큽니다.

QR 코드의 최소 크기도 21x21인데, 검은 상자 안의 21행은 기본 화면 한 페이지를 거의 다 차지합니다. 코드가 조금만 길어져도 전체가 표시되지 않죠. 일반적인 URL 코드는 대개 21행을 넘습니다. 예를 들어:

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

따라서 출력되는 QR 코드의 행/열 크기를 줄일 방법을 찾아야 합니다. 가장 먼저 떠오르는 것은 특이한 Unicode 문자로 조합하는 것입니다:

[caption id="attachment_1325" align="alignnone" width="484"]unicode-block unicode-block[/caption]

열 공백 수를 절��으로 줄이면 가로와 세로 크기를 모두 절반으로 줄일 수 있습니다. 그림과 같이:

[caption id="attachment_1326" align="alignnone" width="768"]terminal-qrcode-small terminal-qrcode-small[/caption]

조금 못생겨졌지만 여전히 사용 가능합니다. 그렇다면 더 작게, 즉 가로세로를 모두 절반씩 더 줄일 수도 있을까요?

같은 방법으로는 불가능합니다. Unicode 문자에는 '하단 1/4 블록', '하단 3/4 블록', '좌측 3/4 블록', '좌측 1/4 블록' 정도만 있어서 부족하기 때문입니다.

3. 오픈 소스 npm 패키지

공교롭게도 위에서 언급한 모든 작업을 누군가 이미 해두었습니다: qrcode-terminal-alpha

워크플로우 도구에 명령줄 QR 코드를 추가하면 빌드 완료 후 즉시 QR 코드가 표시되어 스캔이 훨씬 편리해질 것입니다.

참고 자료

댓글

아직 댓글이 없습니다

댓글 작성