ios - 无法识别条形码中的字符串编码

标签 ios string encoding hex barcode

我的任务是使用iOS设备解码存储在Aztec条码上的数据。我可以访问汇编发送到条形码打印机的字符串的代码,但是打印本身是一个黑匣子。

当我逐步执行此过程时,可以看到发送到打印机的字符串如下所示(请注意,除了前8个字符以外,这是一个加密的字符串):

_36_30_30_30_30_34_7c_5d_49_0b_ea_f7_93_ba_89_d2_c6_c2_41_2a_d7_1c_49_8c_6d_4b_5c_07_5a_ca_7a_6a_c6_d5_d0_6c_f7_20_76_5b_e0_18_46_93_7e_2a_30_0d_14_3a_1a_e5_66_7c_05_f9_df_96_8a_f1_45_a5_4a_6e_2f_89_3f_f0_93_1f_bc_3e_77_5b_27_0c_58_df_55_37_4c_ae_8a_e7_c3_c6_16_5b_57_db_7c_2d_2c_8b_1c_e3_a4_44_1b_c4_ba_6a_c6_98_93_ae_2d_20_6e_9f_e8_0f_eb_bc_9f_2e_8a_e7_cf_da_22_96_e1_74_de_b2_f0_29_ec_b1_c1_75_43_1f_b2_e5_1f_a5_f6_06_3e_97_a1_a1_93_f4_51_4a_c4_14_9f_1a_c2_5b_ba_02_45_44_2b_b3_c2_5b_ba_02_45_44_2b_b3_c2_5b_ba_02_45_44_2b_b3_c2_5b_ba_02_45_44_2b_b3_c2_5b_ba_02_45_44_2b_b3_c2_5b_ba_02_45_44_2b_b3_06_0b_12_75_85_8b_07_fb

打印的条形码如下所示:

enter image description here

但是,当我使用通用的iOS条码读取器将其读回时(我尝试了几次),得到以下信息:

600004|]I�ê÷ºÒÆÂA*×�ImK\�ZÊzjÆÕÐl÷ v[à�F~*0
�:�åf|�ùßñE¥Jn/?ð�¼>w['�XßU7L®çÃÆ�[WÛ|-,�ã¤D�ĺjÆ®- nè�PÐk^¡±xOS5·Óþ�ßá×D¢\���¥ö�>¡¡ôQJÄ��Â[º�ED+³Â[º�ED+³Â[º�ED+³Â[º�ED+³Â[º�ED+³Â[º�ED+³���u�û

这类似于原始字符串(例如前几个字符)。但是我不知道这是什么类型的编码,或者如何将其转换为我期望看到的十六进制代码。

我愿意知道:

1)我在这里看什么?

2)如何将该字符串转换回原始格式?

最佳答案

注意:为清楚起见,您将其称为加密字符串,而我将其称为十六进制代码,以进一步与文章结尾处的随机字符串区别开来。

摘要

我相信您在字符串中看到的编码是混杂的ASCII / ISO-8859-1编码。它省略了一些字符,因此无法从该字符串中恢复原始的十六进制代码。找到能够正确处理条形码的扫描仪后,发现条形码与您的十六进制代码不匹配。

编码方式

Wikipedia says,默认情况下,Aztec中的字节码在0到127之间时会解释为ASCII,在128到255之间时会解释为ISO-8859-1。因此,当您替换字母和符号时,会使用这两种编码中的正确十六进制值您得到以下信息:

36 30 30 30 30 34 7C 5D 49 EA F7 BA D2 C6 C2 41 2A D7 49 6D 4B 5C 5A CA 7A 6A C6 D5 D0 6C F7 20 76 5B E0 46 7E 2A 30 0A 3A E5 66 7C F9 DF F1 45 A5 4A 6E 2F 3F F0 BC 3E 77 5B 27 58 DF 55 37 4C AE E7 C3 C6 5B 57 DB 7C 2D 2C E3 A4 44 C4 BA 6A C6 AE 2D 20 6E E8 50 D0 6B 5E A1 B1 78 4F 53 35 B7 D3 FE DF E1 D7 44 A2 5C

这类似于您的加密十六进制代码,但是省略了一些字节,并且加粗的E8字节之后的内容有所不同。省略的字节全部来自00-1F80-9F范围。 ASCII中的00-1F范围是控制代码,其中大多数很少使用,许多应用程序也不很好地支持。其他范围在ISO-8859-12中未定义。因此,任何试图将这些字节解释为ASCII / ISO-8859-1字符串的应用程序都可能导致无法预测的行为。

如果从加密的十六进制代码中的这些范围中删除字节,则您得到的基本上与我得到的相同,直到E8字节。 E8之后的字节是0F。我以前从未听说过此控制代码,但apparently称为“移入”,其功能是“移出后返回常规字符集”。由于我们已经遇到了字符集问题,因此我只能假定此控制代码是E8字节后的解释错误的原因。

编辑:您最近的编辑之一修改了字符串,现在它包含以下几个字符:。这是Unicode的替换字符,当存在字符编码问题或进程无法解释特定字符时,该字符通常会替换其他字符。在这种情况下,它将替换ASCIIt控件00-1F范围内的许多字节。仍然无法恢复。 80-9F范围仍被省略。

更好的条形码阅读器

为了正确解释条形码,您需要一个不会将十六进制代码解释为编码字符串而是字节流的读取器。至少,您需要一个仍保留00-1F80-9F范围的阅读器。

我发现的这类读者之一是NeoReader。完全有可能您已经尝试过,但是复制粘贴会导致这些特殊代码范围的错误。

我在iOS 7设备上用它扫描了代码,然后点击了该应用程序提供的“复制到剪贴板”按钮。然后,将字符串粘贴在this converter的顶部,然后单击convert。我通常将此转换器用于Unicode内容,但是我发现其他专用的文本至十六进制转换器无法处理字符串及其特殊代码。如果向下滚动到“十六进制代码点”,则尽管它们以一个额外的00 4为前缀,但您应该能够看到所需的十六进制代码。

它产生的字符串(尽管带着一粒盐,但是我遇到了一些复制粘贴错误,并且看起来特殊的控件在发布时被删除了):

600004 |] Iê÷ºÒÆA*×ImK \ZÊzjÆÕÐl÷v [àF〜* 0
:åf|ùßñE¥Jn /?ð¼> w ['XßU7L®çÃÆ[WÛ|-,ã¤DĺjÆ®-nèPÐk^¡±xOS5·Óþßá×D¢\¥ö>¡¡ôQJÄÂ[ºED+³[[ED + ³[ºED+³[ºED+³[ºED+³[ºED+³]uû

十六进制代码比较(差异由< >标记):

Your hex code:    36 30 30 30 30 34 7C 5D 49 0B EA F7 93 BA 89 D2 C6 C2 41 2A D7 1C 49 8C 6D 4B 5C 07 5A CA 7A 6A C6 D5 D0 6C F7 20 76 5B E0 18 46 93 7E 2A 30 <0D> 14 3A 1A E5 66 7C 05 F9 DF 96 8A F1 45 A5 4A 6E 2F 89 3F F0 93 1F BC 3E 77 5B 27 0C 58 DF 55 37 4C AE 8A E7 C3 C6 16 5B 57 DB 7C 2D 2C 8B 1C E3 A4 44 1B C4 BA 6A C6 98 93 AE 2D 20 6E 9F E8 0F <EB BC 9F 2E 8A E7 CF DA 22 96 E1 74 DE B2 F0 29 EC B1 C1 75 43 1F B2 E5> 1F A5 F6 06 3E 97 A1 A1 93 F4 51 4A C4 14 9F 1A C2 5B BA 02 45 44 2B B3 C2 5B BA 02 45 44 2B B3 C2 5B BA 02 45 44 2B B3 C2 5B BA 02 45 44 2B B3 C2 5B BA 02 45 44 2B B3 C2 5B BA 02 45 44 2B B3 06 0B 12 75 85 8B 07 FB
NeoReader string: 36 30 30 30 30 34 7C 5D 49 0B EA F7 93 BA 89 D2 C6 C2 41 2A D7 1C 49 8C 6D 4B 5C 07 5A CA 7A 6A C6 D5 D0 6C F7 20 76 5B E0 18 46 93 7E 2A 30 <0A> 14 3A 1A E5 66 7C 05 F9 DF 96 8A F1 45 A5 4A 6E 2F 89 3F F0 93 1F BC 3E 77 5B 27 0C 58 DF 55 37 4C AE 8A E7 C3 C6 16 5B 57 DB 7C 2D 2C 8B 1C E3 A4 44 1B C4 BA 6A C6 98 93 AE 2D 20 6E 9F E8 0F <81 50 D0 6B 5E A1 B1 78 4F 53 35 B7 D3 FE 1F DF E1 90 D7 44 A2 5C 00 19> 1F A5 F6 06 3E 97 A1 A1 93 F4 51 4A C4 14 9F 1A C2 5B BA 02 45 44 2B B3 C2 5B BA 02 45 44 2B B3 C2 5B BA 02 45 44 2B B3 C2 5B BA 02 45 44 2B B3 C2 5B BA 02 45 44 2B B3 C2 5B BA 02 45 44 2B B3 06 0B 12 75 85 8B 07 FB

差异说明

事实证明,条形码实际上与您的十六进制代码不匹配。我们的两个代码在那个0F字节处出现分歧,而条形码实际上遵循NeoReader的建议。下图显示了该图像,该图像放大了条形码的右下象限(蓝线表示未对数据进行编码的部分,它们将有助于确定扫描仪的方向)。

Partial barcode decoding

this video tutorial的帮助下,我设法手动对条形码的这一部分进行了解码。但是,您的条形码未使用此处显示的字符串编码方法,因为它使用binary shift escape处理8位值。从那里,我相信0A <-> 0D的差异是由于我这一部分的复制粘贴错误。

不幸的是,由于打印机对您来说是一个黑匣子,因此您似乎无法自行解决此问题。

脚注
  • 我找不到Aztec代码规范,但是其行为似乎与默认设置相对一致。
  • ISO-8859-1本质上是ASCII的超集,但从技术上讲,它使ASCII控制代码范围未定义。在实践中通常将其忽略。
  • 唯一的区别是我使用的斜体0A字符,这是换行符。您的字符串包含0D,这是另一个换行符。不同的系统对新行的处理方式不同,它们自动更改新行字符的情况并不罕见。与大多数其他ASCII控制代码不同,通常很好地支持换行符。
  • 原因很复杂。我认为,在处理一些细节时,先按一下转换按钮,它会首先转换为UTF-16(Javascript的本机字符串编码)。 ASCII / ISO-8859-1字符的字节值在UTF-16中相同。但是,UTF-16是16位编码而不是8位编码,因此需要额外的00
  • 太痛苦了。
  • 关于ios - 无法识别条形码中的字符串编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32663952/

    相关文章:

    ios - 如果设备被锁定,CADislayLink 不会触发

    ios - 如何在动画中更改 UITableView 标签 textColor 两次?

    java - 当我的代码运行时,我似乎得到一个空值

    c# - 如何更改此文件的编码?

    mysql - 将 MySQL 中的 UTF8 和 latin1_bin 字段与 PHP 混合

    iphone - 设置按钮的框架大小 : decimal point values

    oracle - 如何在Oracle中一起替换多个字符串

    java - 是否可以在 C# 或 JAVA 中开发一些基于字符串的搜索条件?

    r - R 可以将表情符号字符转换为对应的文本吗?

    ios - 如何在我的 iOS 项目中添加和执行 .sql 文件?