【问题标题】:Unable to identify string encoding from barcode无法从条形码中识别字符串编码
【发布时间】:2015-12-16 07:22:43
【问题描述】:

我的任务是使用 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 P>

打印出来的条码是这样的:

但是,当我使用通用 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) 如何将此字符串转换回原始格式?

【问题讨论】:

  • @zaph 好主意,完成了。谢谢。希望质量没问题(我从屏幕上扫描没问题)。还更新提到它是阿兹特克人。
  • 我认为您在这三个方面都错了(但很高兴收到其他通知)。 1) QR 是二维条码,它仍然是条码 2) 这不是 QR - QR 只是二维条码的一种。这是阿兹台克人,另一种这样的类型。 3) 在这种情况下,字符串既被加密又被编码。我问题中的“之前”内容是发送到打印机的加密字符串。我会看看我是否可以调整我的问题以使其更清楚。
  • 我确实有密钥,而且我对解密部分很满意,但仅将条形码读入可用字符串就是障碍。谢谢。
  • 您应该添加用于从条形码扫描仪读取的代码。
  • @approxiblue 我没有使用任何代码 - 只是使用 App Store 上提供的条码阅读器进行扫描(尝试了一些,结果相同)。

标签: ios string encoding hex barcode


【解决方案1】:

注意:为了清楚起见,您所说的加密字符串,我将称为十六进制代码,以进一步区分您帖子末尾的随机字符串。

总结

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

编码

Wikipedia says 默认情况下1,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 字符串的应用程序都可能导致不可预知的行为。

如果您在加密的十六进制代码中从这些范围中删除字节,您基本上会得到3与我得到的相同的东西,直到 E8 字节。 E8 之后的字节是 0F。我以前从未听说过这个控制代码,但是apparently 它被称为“Shift In”,它的功能是“Shift Out 后返回常规字符集”。由于我们已经遇到了字符集的问题,我只能假设这个控制代码负责E8 字节之后的解释错误。

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

更好的条码阅读器

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

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

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

它产生的字符串(虽然用一粒盐,但我有一些复制粘贴错误,并且在发布时似乎删除了特殊控件):

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 的建议。如下图所示,放大了条码的右下角(蓝线表示不编码数据的部分,它们用于帮助定位扫描仪)。

this video tutorial 的帮助下,我设法手动5 解码那部分条码。但是,您的条形码不使用此处显示的字符串编码方法,因为它使用 binary shift escape 处理 8 位值。从那里我相信0A 0D 的区别是由于我的复制粘贴错误。

很遗憾,由于打印机对您来说是一个黑匣子,因此您似乎无法自己解决此问题。

脚注

  1. 我找不到阿兹特克代码规范,但行为似乎与默认值相对一致。

  2. ISO-8859-1 本质上是 ASCII 的超集,但它在技术上未定义 ASCII 控制代码范围。这在实践中通常被忽略。

  3. 唯一的区别是我有斜体0A 字符,它是一个换行符。你的字符串有0D,另一个换行符。不同的系统以不同的方式处理换行符,自动更改换行符的情况并不少见。与大多数其他 ASCII 控制代码不同,换行符通常得到很好的支持。

  4. 原因很复杂。忽略一些细节,我相信在点击转换按钮后,它首先被转换为 UTF-16(Javascript 的本机字符串编码)。 ASCII/ISO-8859-1 字符的字节值在 UTF-16 中是相同的。但是,UTF-16 是 16 位编码而不是 8 位编码,因此,额外的00

  5. 那很痛苦。

【讨论】:

    【解决方案2】:

    首先,我试用了以下在线条形码阅读器:

    这让我觉得你的条形码可能构造不太好......

    这是你的输出:

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

    这是来自zxing的:

    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�û
    

    可能这种差异是由于您的复制/粘贴操作)


    这是我能找到的匹配项:

    6  0  0  0  0  4  |  ]  I   �  ê  ÷     º     Ò  Æ  Â 
    36 30 30 30 30 34 7c 5d 49  0b ea f7 93 ba 89 d2 c6 c2
    
    A  *  ×  �  I     m  K  \  �  Z  Ê  z  j  Æ  Õ  Ð  l 
    41 2a d7 1c 49 8c 6d 4b 5c 07 5a ca 7a 6a c6 d5 d0 6c
    
    ÷  v  [  à  �  F     ~  *  0  �     :  �  å  f     | 
    f7 20 76 5b e0 18 46 93 7e 2a 30 0d 14 3a 1a e5 66 7c
    
    �  ù  ß        ñ  E  ¥  J  n  /     ?  ð     �  ¼  > 
    05 f9 df 96 8a f1 45 a5 4a 6e 2f 89 3f f0 93 1f bc 3e
    
    w  [  '  �  X  ß  U  7  L   ®     ç  Ã  Æ  �  [  W  Û  
    77 5b 27 0c 58 df 55 37 4c  ae 8a e7 c3 c6 16 5b 57 db 
    
    |  -  ,  �     ã  ¤  D  �  Ä  º  j  Æ        ®  -     
    7c 2d 2c 8b 1c e3 a4 44 1b c4 ba 6a c6 98 93 ae 2d 20 
    
    n     è  �  P 
    6e 9f e8 0f eb
    

    而这似乎是某种Unicode UCS-2 编码。

    在此之后,我无法解释输出和预期的十六进制值之间的区别

    【讨论】:

    • @zaph 你说得对……但你不能说它是随机的,有 60 多个字符匹配……
    • @zaph 那么你如何解释如果你解码 OP 给出的第 113 个十六进制字节,你会得到 exact 相同的字符?
    • “给定的 hexa 值已经加密” - 是的。我追求的是可靠的解码,而不是解密。我可以很好地解密字符串,只要我能从条形码中读取该死的东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-02
    • 2021-10-15
    • 2016-02-01
    • 1970-01-01
    相关资源
    最近更新 更多