在QR码符号中编码UTF-8字符

4
自 iOS 7 开始,可以通过名为 CIQRCodeGeneratorCore Image 框架的 CIFilter 生成 QR Code。
根据文档,苹果指出用于生成 QR Code 的字符串必须使用 NSISOLatin1StringEncoding 进行编码。

要从字符串或 URL 创建 QR Code,请使用 NSISOLatin1StringEncoding 字符串编码将其转换为 NSData 对象。

然而,我尝试使用 NSUTF8StringEncoding 对中文字符进行编码,结果效果很好。你认为我使用 NSUTF8StringEncoding 会有问题吗?是否有已知问题?
2个回答

4
以下是一些通用建议,了解Core Image框架的人可能能够提供更具体的答案。尽管如此,我希望它能澄清为什么库提供这样特定的编码建议,忽视该建议可能会带来的后果以及如何编码不可通过Latin-1获得的字符。
一般来说,QR码(“QR Code 2005”)的ISO / IEC 18004标准以及所有其他国际2D条形码标准都规定,在解释读者返回的QR码字节序列时必须使用Latin-1字符编码,除非数据中提供了指定替代字符编码的扩展通道解释(ECI)序列。
然而,用户通常使用UTF-8对数据进行编码,因此在实践中,大多数条形码阅读器使用专有启发式方法来“猜测”内容是否按照Latin-1以外的其他编码方式进行编码,例如UTF-8。 在许多情况下,这会导致歧义,并且将导致误读,特别是当任意数据用于开放应用程序时。
如果您打算严格执行,并且需要使用UTF-8对数据进行编码,则必须在UTF-8数据之前设置ECI 000026的编码库。

2020年更新:我已经撰写了一篇详细的文章,描述了这个问题以及标准机构目前正在进行的工作,以促进ECI的使用:https://www.linkedin.com/pulse/enhanced-channel-interpretation-terry-burton/

已分配的ECI代码注册表可从AIM商店获得,费用为"ECI Part 3: Register"

[*] 使用CIQRCodeGenerator似乎不是这种情况。


谢谢您的解释!现在我明白了! - Sébastien MICHOY
ECI第三部分不再免费,非会员需支付200美元! https://web.aimglobal.org/External/WCPages/WCEcommerce/eComListPage.aspx?Category=4&Keyword=ECI - jmd

1
“ISO-8859-1”是QR码的默认编码。QR码有4种文本存储模式:数字(0-9)、字母数字混合(数字加大写A-Z、空格和8个标点符号)-总共45个字符、8位(默认为“ISO-8859-1”编码的文本)和汉字(范围在8140-9FFC和E040-EBBF之间的“Shift_JIS”编码JIS X 0208字符)。因此,CIQRCodeGenerator使用NSISOLatin1StringEncoding来适应QR码中的8位文本编码模式,因为“ISO-8859-1”是QR码的默认编码。要在8位字符串中使用UTF-8编码而不是默认的“ISO-8859-1”,实现必须在字符串前插入ECI(扩展通道解释)。

ECI是QR码的一个可选附加功能。ECI使数据编码使用除默认设置以外的字符集。它还允许对其他数据进行解释(例如,使用定义的压缩方案紧凑数据)或对特定行业需求进行编码。

ECI协议在AIM ECI规范中完全定义(由AIM,Inc - 20399 Route 19,Suite 203,Cranberry Township,Pennsylvania 16066 USA开发)。它是与QR码规范不同的规范。ECI协议提供了一种在打印和解码之前指定字节值特定解释的方法。该规范可在https://www.aimglobal.org/technical-symbology.html以50美元的价格获得。

不幸的是,并非所有QR码解码器实现都能处理ECI协议,即使是像将默认编码更改为UTF-8这样的基本操作。大多数实现使用一种或另一种字符编码检测算法来猜测编码,即使编码在已解码的QR码的ECI中明确指定。

使用检测算法的需求可能是由于最初的QR码标准在2000年发布时(ISO/IEC 18004:2000)默认采用8位拉丁/假名字符集,符合JIS X 0201(JIS8也称为ISO-2022-JP)作为8位模式的编码方式,因此需要使用检测算法。而在2005年发布的更新标准将默认编码更改为ISO-8859-1。
例如,带有MIUI Global v11.0.3的小米手机无法正确显示使用UTF-8编码的一串西里尔文字符,即使通过ECI指定了该编码方式。西里尔文字符会显示为问号。但如果在西里尔文文本中添加一个中文/日文字符(例如日),小米就能正确显示整个文本。
应该制定一套QR解码器的最佳实践。该套实践应规定,在给定ECI扩展以指定字符编码的情况下,不应使用字符编码检测算法来覆盖指定的编码方式。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接