들어가며
명령줄에서 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[/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[/caption]
열 공백 수를 절��으로 줄이면 가로와 세로 크기를 모두 절반으로 줄일 수 있습니다. 그림과 같이:
[caption id="attachment_1326" align="alignnone" width="768"]
terminal-qrcode-small[/caption]
조금 못생겨졌지만 여전히 사용 가능합니다. 그렇다면 더 작게, 즉 가로세로를 모두 절반씩 더 줄일 수도 있을까요?
같은 방법으로는 불가능합니다. Unicode 문자에는 '하단 1/4 블록', '하단 3/4 블록', '좌측 3/4 블록', '좌측 1/4 블록' 정도만 있어서 부족하기 때문입니다.
3. 오픈 소스 npm 패키지
공교롭게도 위에서 언급한 모든 작업을 누군가 이미 해두었습니다: qrcode-terminal-alpha
워크플로우 도구에 명령줄 QR 코드를 추가하면 빌드 완료 후 즉시 QR 코드가 표시되어 스캔이 훨씬 편리해질 것입니다.
참고 자료
-
QR Code Generator: 온라인 QR 코드 생성기
-
kazuhikoarase/qrcode-generator: JS API
아직 댓글이 없습니다