Step to UEFI (167)Shell 下的二维码显示

二维码是一种非常方便的对手机输入的方式,现在的日常生活中二维码几乎随处可见,无论是手机支付还是网页分享都能看到它的身影。最近研究了一下如何在生成二维码,找到【参考1】提供的一个C语言库。经过简单调试即可在 Shell 下跑起来。
实例代码如下:

#include <stdio.h>
#include <string.h>
#include "qr_encode.h"

int main(void)
{
	int side, i, j, a, ecclevel;
	uint8_t bitdata[QR_MAX_BITDATA];
	char str[2048];

	printf("ECC Level [LMQH]: ");
	if (!fgets(str, sizeof(str), stdin)) {
		return 1;
	}
	switch (str[0]) {
	case 'l':
	case 'L':
		ecclevel = QR_LEVEL_L;
		break;
	case 'm':
	case 'M':
	default:
		ecclevel = QR_LEVEL_M;
		break;
	case 'q':
	case 'Q':
		ecclevel = QR_LEVEL_Q;
		break;
	case 'h':
	case 'H':
		ecclevel = QR_LEVEL_H;
		break;
	}

	printf("Enter string: ");
	if (!fgets(str, sizeof(str), stdin)) {
		return 1;
	}
	// remove newline
	if (str[strlen(str) - 1] == '\n') {
		str[strlen(str) - 1] = 0;
	}

	side = qr_encode(ecclevel, 0, str, 0, bitdata);

	printf("side: %d\n", side);

	for (i = 0; i < side + 2; i++) printf("██");
	printf("\n");
	for (i = 0; i < side; i++) {
		printf("██");
		for (j = 0; j < side; j++) {
			a = i * side + j;
			printf((bitdata[a / 8] & (1 << (7 - a % 8))) ? "  " : "██");
		}
		printf("██");
		printf("\n");
	}
	for (i = 0; i < side + 2; i++) printf("██");
	printf("\n");

	return 0;
}

运行之后会要求你选择容错程度,容错性越高面积和复杂度会越高。然后要求你输入需要编码的字符串,之后就生成 ASCII 组成的二维码了。编译后的 EFI 可以在 NT32或者实体机上运行,下面就是在 KBL-R HDK 上运行的结果(有兴趣的朋友可以直接用手机扫描一下):

完整的代码和库下载:

参考:
1. https://github.com/trezor/trezor-qrenc

《Step to UEFI (167)Shell 下的二维码显示》有8个想法

  1. Hi Sir
    請問一下你的 build 環境是什麼?
    我用 VS2017 會有錯誤

    c:\leo\uefi\edk2\StdLib\EfiSocketLib\Socket.c(579): error C2220: 將警告視為錯誤處理 - 沒有產生 'object' 檔案
    c:\leo\uefi\edk2\StdLib\EfiSocketLib\Socket.c(579): warning C4459: 'errno' 的宣告會隱藏全域宣告
    c:\leo\uefi\edk2\StdLib\Include\errno.h(43): note: 請參閱 'errno' 的宣告
    c:\leo\uefi\edk2\StdLib\EfiSocketLib\Socket.c(1343): warning C4459: 'errno' 的宣告會隱藏全域宣告
    c:\leo\uefi\edk2\StdLib\Include\errno.h(43): note: 請參閱 'errno' 的宣告
    c:\leo\uefi\edk2\StdLib\EfiSocketLib\Socket.c(1486): warning C4459: 'errno' 的宣告會隱藏全域宣告
    c:\leo\uefi\edk2\StdLib\Include\errno.h(43): note: 請參閱 'errno' 的宣告
    c:\leo\uefi\edk2\StdLib\EfiSocketLib\Socket.c(1898): warning C4459: 'errno' 的宣告會隱藏全域宣告
    c:\leo\uefi\edk2\StdLib\Include\errno.h(43): note: 請參閱 'errno' 的宣告
    c:\leo\uefi\edk2\StdLib\EfiSocketLib\Socket.c(2760): warning C4459: 'errno' 的宣告會隱藏全域宣告
    c:\leo\uefi\edk2\StdLib\Include\errno.h(43): note: 請參閱 'errno' 的宣告
    c:\leo\uefi\edk2\StdLib\EfiSocketLib\Socket.c(2980): warning C4459: 'errno' 的宣告會隱藏全域宣告
    c:\leo\uefi\edk2\StdLib\Include\errno.h(43): note: 請參閱 'errno' 的宣告

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注