UTF-8现在是非ASCII字符的QR码的首选编码吗?

Gon*_*nzo 4 encoding qr-code utf-8 iso-8859-1 character-encoding

谷歌使用UTF-8作为其非常流行的编码器的默认值.从我所看到的,他们甚至没有添加字节顺序标记.

问题是大多数扫描仪似乎仍然使用JIS8(QR 2000)而不是iso-8859(QR 2005)作为默认值,因此它主要不能使用iso-8859进行编码.

似乎utf-8是唯一的选择,即使它违反了规范.

编辑:我将使用没有ECI而没有BOM的utf-8.反对所有的规范和精神,但目前效果最好.

Sea*_*wen 12

规范说ISO-8859-1是字节模式编码的默认设置.但是在实践中,是的,你会在日本看到很多Shift-JIS,或UTF-8.

UTF-8是正确的选择.要正确地执行此操作,您需要在流中添加一些指示它是UTF-8.规范确实允许这样做.您需要在字节段之前加上指示UTF-8 的ECI段.

如果您发送编码为UTF-8的提示,zxing编码器将为您执行此操作.

  • @Phelix:不要在UTF-8流中使用BOM.它在某些环境中解决了很多问题. (3认同)
  • 是的,我错了.BOM成为解析流中的(不可见)字符U + FEFF.我会看到忽略它是多么困难.但是你应该省略BOM. (3认同)
  • 好吧,我测试了,ECI没有用.对于BOM,我可能会选择tchrist并将其遗漏.这来自UTF-8维基百科页面:"因为检查文本是否有效UTF-8是非常可靠的(大多数随机字节序列不是有效的UTF-8),所以不必使用[BOM]." (2认同)

Max*_*tin 6

BOM 没有帮助

\n

我的经验表明 BOM 没有帮助。如果 QR 扫描仪无法显示正确编码的 UTF-8 字符串(数据流中的 8 位字节模式)中的字符串,即使使用 ECI,添加 BOM 也没有任何区别。

\n

即使使用正确编码的 UTF-8,扫描仪也会失败

\n

作为无法显示正确 UTF-8 字符串的扫描仪的示例,以配备 MIUI Global v11.0.3(及其本机扫描仪应用程序)的小米手机为例。即使 ECI 中指定了此字符集,这些手机也无法正确显示以 UTF-8 编码的西里尔字符字符串。西里尔字母显示为问号。但是,如果您在西里尔文字中添加中文/日文字符(例如\xe6\x97\xa5),小米将正确显示整个文本。这与 BOM 无关。

\n

这些是重要的实际字符,而不是编码

\n

您可能认为在 QR 码中使用 UTF-8 而不是 ISO-8859-1 更好,因为 ISO-8859-1 不是 2000 年发布的早期 QR 码标准 (ISO/IEC 18004:2000) 中的默认编码。该标准确实根据 JIS X 0201(JIS8 也称为 ISO-2022-JP)指定 8 位拉丁/假名字符集作为 8 位模式的默认编码,而 2005 年发布的更新标准确实将默认值更改为ISO-8859-1。因此,您认为 \xe2\x80\x9cit 大多数情况下无法使用 iso-8859 进行编码\xe2\x80\x9d。\n这取决于 US-ASCII 字符是否足以满足您的需求(具体来说,20-范围内的可打印 ANSI X3.4-1986 字符7E,并且您不需要在加泰罗尼亚语、法语、加利西亚语、德语、奥克西唐语和西班牙语等语言中使用带元音变音/分音符号的 ISO-8859-1 字符。

\n

如果您只需要 US-ASCII,那么使用不带任何 ECI 的 ISO-8859-1 比带 ECI 的 UTF-8 更安全。无论如何,US-ASCII 字符的八位字节字符串的范围为20-7E都是相同的。如果您仅使用 US-ASCII 字符,扫描仪使用的启发式软件应该能够自动找出所使用的字符集。如果您需要带有元音变音/分音符号的字符,请使用 UTF-8。这并不是因为在 QR 码标准的 2000 年和 2005 年修订版之间,默认编码已从 JIS X 0201 更改为 ISO-8859-1,而是因为 QR 扫描仪使用启发式方法自动检测编码,而这种启发式方法在某些情况下会失败。

\n

为什么 QR 扫描仪使用启发式方法来检测编码

\n

如您所知,QR 码有 4 种存储文本的模式:(1) 数字、(2) 字母数字、(3) 8 位和 (4) 汉字。

\n

所以,QR码标准本身并不支持UTF-8。要在 8 位字符串中使用 UTF-8 编码(而不是默认的 \xe2\x80\x9cISO-8859-1\xe2\x80\x9d 或 \xe2\x80\x9cJIS8\xe2\x80\x9d),实现必须在该字符串之前插入 ECI(扩展通道解释)。ECI 是 QR 码的一项可选附加功能,但它至少在 2000 年在最早的 QR 码标准中定义。ECI 允许使用默认字符集以外的字符集进行数据编码。它还支持其他数据解释(例如使用定义的压缩方案的压缩数据)或其他行业特定要求进行编码。

\n

ECI 协议是在AIM, Inc开发的规范中定义的,该协议不是免费提供的,但可以在https://www.aimglobal.org/technical-symbology.html上以 50 美元的价格购买

\n

扫描仪可能会忽略 ECI 协议

\n

不幸的是,并不是所有的 QR 扫描仪都能处理 ECI 协议,即使是像将默认编码更改为 UTF-8 这样的基本操作也是如此。大多数实现都使用启发式方法,即使用一种或另一种字符编码检测算法来猜测编码,即使在解码的 QR 码的 ECI 中明确指定了编码。他们使用启发式方法不仅是因为 2000 年至 2005 年间默认编码从 JIS8 更改为 ISO-8859-1。主要原因是缺乏适当的 ECI 协议支持,这可能是由于 QR 码规范和 AIM ECI协议规范是不同的文档。某些 QR 编码器不通过 ECI 指定字符编码,而是对 8 位字符串使用不同的编码(JIS8、Shift_JIS、ISO-8859-1、UTF-8),因此扫描仪必须应对这种情况。

\n

您写道 \xe2\x80\x9cit 似乎 utf-8 是唯一的选择\xe2\x80\x9d,但扫描仪使用启发式方法,即使使用 UTF-8 也可能会失败,如我给出的小米示例中所示。您还根据规范 \xe2\x80\x9d 编写了 UTF-8 \xe2\x80\x9cis,但只有在未通过 ECI 显式指定 UTF-8 编码时才会如此。

\n

ECI 和 UTF-8 的替代方案,但不是彻底解决问题的方法

\n

PS 还有一种方法可以替代使用 ECI。您可以使用 \xe2\x80\x9cKanji\xe2\x80\x9d 模式对带有变音/分音符号的拉丁字符或西里尔字符进行编码。在此模式下, \xe2\x80\x9cShift_JIS\xe2\x80\x9d 用于对8140-9FFCE040-范围内的 JIS X 0208 字符进行编码EBBF。在这里,您无法按字节码 20 对空格等其他范围内的字符进行编码,但您可以将其编码为 JIS X 0208 第 1 行第 21 列,即 2121)。由于 JIS X 0208 包含罗马字母(第 3 行)、希腊字母(第 6 行)和西里尔字母(第 7 行)行,以及标点符号等特殊字符(第 1 行和第 2 行),因此您可以使用元音变音/分音符号或西里尔字母对拉丁字符进行编码文本(包括空格和标点符号)完全采用 JIS 字符范围8140-9FFCE040- EBBF。在这种情况下不需要 ECI 扩展。但不能保证扫描仪软件中的启发式方法不会破坏您正确编码的文本。

\n

结论

\n

使用 UTF-8 并通过 ECI 指定它并不能完全解决问题(因为在这种情况下某些扫描仪无论如何都会使用容易出错的启发式方法),但至少它对兼容的扫描仪有所帮助,不像 BOM 根本没有帮助。

\n

  • 对于模型配置,应用程序或主机驱动程序不可能通过单向接口“窥视”条形码的内部码字/比特流以确定有效的精确模式。因此,解码后的消息是可用的,并且为了避免歧义,确定将其解释为 Latin-1,除非 ECI 有效(如消息开头的符号标识符所指示)。 (2认同)
  • 在移动应用程序或嵌入式应用程序中,阅读器和运行某些应用程序的主机之间没有物理区别,因此该模型界面是不可见的实际用途。因此,“压缩模式(汉字等)”(用于代码字优化目的)和字符编码(用于解释目的)之间的区别不再明显。这会导致分层违规,开发人员使用任何可用的信息来窥探 QR 码的内部编码,以推断出无意的含义。 (2认同)
  • QR 码 2005 标准的目标是合理化早期 QR 码标准中不符合现行框架假设的元素。(例如,当 ECI 未生效时,IIRC 早期版本省略了定义默认字符编码。)问题在于,许多实现将消息数据通过管道传输到工具包的文本小部件中,这会导致自动检测有效的字符编码。从条形码的角度来看,字符集是灾难性的,它旨在成为一种健全且完整的传输,而不是看起来大多数情况下都有效的东西,直到它不起作用。 (2认同)
  • 随着越来越多的应用程序强制对非 ECI 消息进行 Latin-1 编码,情况正在逐渐改善。当 ECI 支持无处不在时,您可以指定将输出消息或消息段解释为 Shift JIS (ECI \000020),并且还可以使用汉字在 QR 码符号的内部比特流中有效编码这些消息字节压缩模式。最近的条形码(例如 HanXin)支持多字节语言的几种附加压缩模式,但在模型接口框架上使用相同的 ECI 协议来表示解释。 (2认同)