在 bash 中使用 qrencode 和 zbarimg 编码/解码二维码中的二进制数据

Zor*_*b29 2 binary bash encode decode qr-code

我有一些二进制数据,我想用二维码编码,然后能够解码,所有这些都在 bash 中。搜索后,看起来我应该qrencode用于编码和zbarimg解码。经过一些故障排除后,我仍然无法解码我编码的内容

知道为什么吗?目前我最接近解决方案的是:

$ dd if=/dev/urandom bs=10 count=1 status=none > data.bin
$ xxd data.bin
00000000: b255 f625 1cf7 a051 3d07                 .U.%...Q=.
$ cat data.bin | qrencode -l H -8 -o data.png
$ zbarimg --raw --quiet data.png | xxd
00000000: c2b2 55c3 b625 1cc3 b7c2 a051 3d07 0a    ..U..%.....Q=..
Run Code Online (Sandbox Code Playgroud)

看起来我不是很远,但仍然有一些东西。

编辑 1:一个可能的解决方法是使用 base64 包装,如@leagris 的回答中所述。

编辑 2:使用 base64 编码使消息的大小加倍。我首先使用二进制文件的原因是为了节省大小,所以我想避免这种情况。不接受@leagris 的答案,因为我希望它是“完整的二进制文件”,抱歉。

编辑 3:截至 2020 年3 月 3 日,这似乎是一个众所周知的问题,zbarimg解决此问题的拉取请求正在进行中:

https://github.com/mchehab/zbar/pull/64

编辑 4:如果您知道 linux 上的另一个命令行工具能够解密带有二进制内容的二维码,请随时告诉我。

Mat*_*ira 7

我的拉取请求已被应用。ZBar 0.23.1及更新版本将能够解码二进制二维码:

zbarimg --raw --oneshot -Sbinary qr.png
zbarcam --raw --oneshot -Sbinary
Run Code Online (Sandbox Code Playgroud)

二维码有多种编码方式。最简单、最常用和广泛支持的是适用于简单文本的字母数字编码。字节编码允许在二维码中存储任意 8 位数据。的ECI模式是像8位模式但具有额外的元数据,告诉解码器的字符集来使用,以解码该二进制数据回文本。是已知 ECI 值及其代表的字符编码的列表。例如,当解码器遇到 ECI 26 模式 QR 码时,它知道将二进制数据解码为 UTF-8。

qrencode工具正确地完成了它的工作:它正在创建一个字节模式的二维码,并将您提供的数据作为其内容。问题是大多数解码器被明确设计为首先处理文本数据。原始二进制数据的检索充其量只是一个细节。

zbar库的当前版本将字节模式 QR 码视为未知 ECI 模式 QR 码。如果未指定字符集,它将尝试猜测编码并将数据转换为该编码。这很可能会破坏二进制数据。正如你所指出的,我在issue #55 中提出了这个问题,一段时间后设法提交了一个 pull request来改进它。如果合并,库将具有binary解码器选项,该选项将指示解码器返回原始二进制数据而不进行转换。数据修改的另一个来源是命令行工具倾向于将换行符附加到输出。我提交了一个拉取请求以允许用户阻止这种情况,它已经被合并了。

zxing-cpp还将尝试猜测二维码中二进制数据的编码。评论表明 QR 码规范要求解码器选择一种编码,而不指定默认值或允许它们返回原始二进制数据。为了实现这一点,二进制数据被复制到一个字节数组中,该数组可以通过DecoderResult. 当我有一些空闲时间,我打算写zximgzxcam工具,与此库二进制解码支持。

始终可以将二进制数据编码为 base 64,并将结果编码为字母数字 QR 码。但是,base 64 编码会增加数据的大小,并且字母数字模式不允许使用 QR 码的最大容量。在评论中,您提到您打算将二进制二维码用于:

我想要一个包来有效地以一种使恢复容易的格式转储一些 gpg 东西。

这就是我试图通过我的拉取请求启用的确切用例:更容易恢复的paperkey。4096 位 RSA 密钥可以直接以 8 位模式进行 QR 编码,但不能以字母数字模式作为基本 64 位编码数据进行编码。

  • 是的,100%同意,我也想要一个“更好的纸钥匙”:) (2认同)