【问题标题】:Decode String in an unknown format以未知格式解码字符串
【发布时间】:2019-10-03 08:36:05
【问题描述】:

我有一个以这种格式返回的字符串:

\n\bbcn_test\u0012\u00041.14\u001a\u0004escc\"\u0004vscc*(\u0012\f\u0012\n\b\u0001\u0012\u0002\b\u0000\u0012\u0002\b\u0001\u001a\u000b\u0012\t\n\u0007Org1MSP\u001a\u000b\u0012\t\n\u0007Org2MSP2D\n \ufffd\ufffda\ufffd\ufffd\ufffd3RU4\ufffd\ufffdR\ufffd\ufffd\ufffd\ufffd@\ufffd\ufffds\b\ufffd\u0014\ufffd\ufffd.\ufffd!\ufffd\u0012 s\ufffd\ufffdc\ufffd6\ufffd\ufffd@\ufffd\u001eF\ufffdƳ\ufffdi\ufffd$\ufffd\ufffd4\ufffdgP\ufffd:\ufffdt\u000e: 6ђ\ufffd\ufffd3\u007fJ\ufffdHt\u0004\ufffd\ufffd\ufffd\ufffd^{\\\ufffd\u001d\ufffd\ufffd\ufffd\ufffd\ufffd3\ufffdb?@\ufffdB,\u0012\f\u0012\n\b\u0001\u0012\u0002\b\u0000\u0012\u0002\b\u0001\u001a\r\u0012\u000b\n\u0007Org1MSP\u0010\u0001\u001a\r\u0012\u000b\n\u0007Org2MSP\u0010\u0001

\n\u0004mycc\u0012\u00031.0\u001a\u0004escc\"\u0004vscc*,\u0012\f\u0012\n\b\u0002\u0012\u0002\b\u0000\u0012\u0002\b\u0001\u001a\r\u0012\u000b\n\u0007Org1MSP\u0010\u0003\u001a\r\u0012\u000b\n\u0007Org2MSP\u0010\u00032D\n \ufffd\u0011}\ufffdT\ufffdV \u0010l\ufffdNT\ufffd\ufffdz\ufffd\ufffd\ufffdv+\ufffd˹5;\ufffd@q\ufffd\ufffd\u000e\u0012 \u0007\u001f\u0014)\u001e\u0015+\ufffd\ufffd\ufffd\ufffd\ufffd\ufffd\ufffdt\ufffd\u0013ak\ufffd\u0015J\ufffd\ufffd\ufffd\ufffdZ\u0017_c&: y\ufffd\ufffdw\ufffdnN\ufffd<\ufffd3^v\ufffdbIB`M\ufffd\ufffd\ufffd)&\u0007x\ufffd;(u\ufffdLB,\u0012\f\u0012\n\b\u0001\u0012\u0002\b\u0000\u0012\u0002\b\u0001\u001a\r\u0012\u000b\n\u0007Org1MSP\u0010\u0001\u001a\r\u0012\u000b\n\u0007Org2MSP\u0010\u0001

我正在尝试对其进行解码以获得有效的字符串,但我不明白它是用哪种格式编写的,什么是好的解码器。

如何确定格式是什么以及如何解码?

【问题讨论】:

  • 你在这里写的是一个有效的字符串(我们知道这是因为我们的网络浏览器可以很容易地显示它)。你认为解码后的字符串应该是什么?如果您认为这是一种编码,为什么您认为它编码了一个可读的字符串(对我来说它看起来像二进制数据,而不是字符数据)?你从哪里得到这些数据的? API 应该告诉你它返回了什么。
  • 顺便说一句,这看起来完全像 TLV(类型-长度-值)格式。第一个字节是类型0x0a,后接长度0x08,后接8字节数据(“bcn_test”),后接类型(0x12),后接长度(0x04),后接4字节数据(“ 1.14") 等。
  • 啊;可能是 ASN.1,我猜是 Hyperledger?我会检查协议文档以了解您正在使用的任何软件,它应该解释如何解码它。

标签: string utf-8


【解决方案1】:

您拥有的是已被字符串化为人类可读格式的二进制数据。

所以,你需要先解析字符串,将其字符转换为字节。

以转义序列格式编码的子字符串(前面是 '\' 字符后跟 1-4 个字符)被解码为特定字节,如下所示:

  • \b -> 0x08
  • \t -> 0x09
  • \n -> 0x0A
  • \f -> 0x0C
  • \r -> 0x0D
  • \" -> 0x22
  • \' -> 0x27
  • \\ -> 0x5C
  • \u00## + \uff## -> 0x##ff 是由于字节 >= 0x80 的符号扩展)

字符串中任何未转义的字符都将按原样转换(即,简单地从 16 位 Char 转换为 8 位 Byte,忽略高 8 位)。

让我们看看您提供的第一个字符串:

\n\bbcn_test\u0012\u00041.14\u001a\u0004escc\"\u0004vscc*(\u0012\f\u0012\n\b\u0001\u0012\u0002\b\u0000\u0012\u0002\b\ u0001\u001a\u000b\u0012\t\n\u0007Org1MSP\u001a\u000b\u0012\t\n\u0007Org2MSP2D\n \ufffd\ufffda\ufffd\ufffd\ufffd3RU4\ufffd\ufffdR\ufffd\ufffd\ufffd\ufffd@ \ufffd\ufffds\b\ufffd\u0014\ufffd\ufffd.\ufffd!\ufffd\u0012 s\ufffd\ufffdc\ufffd6\ufffd\ufffd@\ufffd\u001eF\ufffdƳ\ufffdi\ufffd$\ufffd\ufffd4\ ufffdgP\ufffd:\ufffdt\u000e: 6ђ\ufffd\ufffd3\u007fJ\ufffdHt\u0004\ufffd\ufffd\ufffd\ufffd^{\\ufffd\u001d\ufffd\ufffd\ufffd\ufffd\ufffd3\ufffdb?@\ ufffdB,\u0012\f\u0012\n\b\u0001\u0012\u0002\b\u0000\u0012\u0002\b\u0001\u001a\r\u0012\u000b\n\u0007Org1MSP\u0010\u0001\u001a\r \u0012\u000b\n\u0007Org2MSP\u0010\u0001

分解各个序列进行解码:

\n \b b c n _ t e s t \u0012 \u0004 1 . 1 @987654360 @ \u001a \u0004 e s c c \" \u0004 v s c c * ( \u0012 \f @ 987654377@ \n \b \u0001 \u0012 \u0002 \b \u0000 \u0012 \u0002 \b \u0001 \u001a \u000b \u0012 \t \n \u0007 O r g 1 M S P \u001a \u000b \u0012 \t \n \u0007 O r @987654410 @ 2 M S P 2 D \n \ufffd \ufffd a \ufffd \ufffd \ufffd 3 R @ 987654427@@ 987654428@ \ufffd \ufffd R \ufffd \ufffd \ufffd \ufffd @ \ufffd \ufffd s \b \ufffd \u0014 \ufffd \ufffd . \ufffd ! \ufffd \u0012 s \ufffd \ufffd c \ufffd 6 \ufffd \ufffd @ \ufffd @987654461 @ F \ufffd Ƴ \ufffd i \ufffd $ \ufffd \ufffd 4 \ufffd g P \ufffd : \ufffd @ 987654478@ \u000e : 6 ђ1\ufffd \ufffd 3 \u007f J \ufffd H t @ 987654492@ \ufffd \ufffd \ufffd \ufffd ^ { \\ \ufffd \u001d \ufffd \ufffd \ufffd \ufffd \ufffd 3 \ufffd b@98765 4510@ @ \ufffd B , \u0012 \f \u0012 \n \b \u0001 \u0012 \u0002 \b \u0000 \u0012 \u0002 \b \u0001 \u001a \r \u0012 \u000b \n \u0007 O r g 1 M S P \u0010 @987654543 @ \u001a \r \u0012 \u000b \n \u0007 O r g 2 M S P \u0010 \u0001

并将它们转换为字节:

0x0A 0x08 0x62 0x63 0x6E 0x5F 0x74 0x65 0x73 0x74 0x12 0x04 0x31 0x2E 0x31 @987654574 @ 0x1A 0x04 0x65 0x73 0x63 0x63 0x22 0x04 0x76 0x73 0x63 0x63 0x2A 0x28 0x12 0x0C @ 987654591@ 0x0A 0x08 0x01 0x12 0x02 0x08 0x00 0x12 0x02 0x08 0x01 0x1A 0x0B 0x12 0x09 0x0A 0x07 0x4F 0x72 0x67 0x31 0x4D 0x53 0x50 0x1A 0x0B 0x12 0x09 0x0A 0x07 0x4F 0x72 @987654624 @ 0x32 0x4D 0x53 0x50 0x32 0x44 0x0A 0x20 0xFD 0xFD 0x61 0xFD 0xFD 0xFD 0x33 0x52 @ 987654641@@ 987654642@ 0xFD 0xFD 0x52 0xFD 0xFD 0xFD 0xFD 0x40 0xFD 0xFD 0x73 0x08 0xFD 0x14 0xFD 0xFD 0x2E 0xFD 0x21 0xFD 0x12 0x20 0x73 0xFD 0xFD 0x63 0xFD 0x36 0xFD 0xFD 0x40 0xFD @987654675 @ 0x46 0xFD 0x59 0xFD 0x69 0xFD 0x24 0xFD 0xFD 0x34 0xFD 0x67 0x50 0xFD 0x3A 0xFD @ 987654692@ 0x0E 0x3A 0x20 0x36 ђ10xFD 0xFD 0x33 0x7F 0x4A 0xFD 0x48 0x74 @ 987654706@ 0xFD 0xFD 0xFD 0xFD 0x5E 0x7B 0x5C 0xFD 0x1D 0xFD 0xFD 0xFD 0xFD 0xFD 0x33 0xFD 0x62@98765 4724@ 0x40 0xFD 0x42 0x2C 0x12 0x0C 0x12 0x0A 0x08 0x01 0x12 0x02 0x08 0x00 0x12 0x02 0x08 0x01 0x1A 0x0D 0x12 0x0b 0x0A 0x07 0x4F 0x72 0x67 0x31 0x4D 0x53 0x50 0x10 @987654757 @ 0x1A 0x0D 0x12 0x0B 0x0A 0x07 0x4F 0x72 0x67 0x32 0x4D 0x53 0x50 0x10 0x01

解码完字节后,您可以根据需要解释二进制数据。它似乎采用一种类型-长度-值格式,就像@RobNapier 在对您的问题的评论中建议的那样:

顺便说一句,这看起来完全像 TLV(类型-长度-值)格式。第一个字节是类型0x0a,后接长度0x08,后接8字节数据(“bcn_test”),后接类型(0x12),后接长度(0x04),后接4字节数据(“ 1.14") 等。

0x0A (Type 10), 0x08 (Len 8)
0x62 0x63 0x6E 0x6E 0x5F 0x5F 0x65 0x73@9876547870x650x73987654787

0x12 (Type 18) 0x04 (Len 4)
0x31 0x2E 0x31 0x34 (1.14)

0x1A (Type 26) 0x04 (Len 4)
0x65 0x73 0x63 0x63 (escc)

0x22 (Type 34) 0x04 (Len 4)
0x76 0x73 0x63 0x63 (vscc)

等等……

1:但是,我不确定如何正确解码原始字符串中的ђ。它是 Unicode 代码点 U+0452 CYRILLIC SMALL LETTER DJE,在 Java 中 Char 是字节 0x04 0x52。被截断为0x040x52,或解释为像Windows-1251 这样的西里尔字符集,它会是字节0x90,它与TLV 格式的其余部分不匹配。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 2019-05-01
    • 2019-03-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-03
    相关资源
    最近更新 更多