【问题标题】:Convert JSON Base64 string to String in Java将 JSON Base64 字符串转换为 Java 中的字符串
【发布时间】:2017-03-04 15:49:55
【问题描述】:

我正在尝试使用 com.google.protobuf.util.JsonFormat 类将 protobuf 流转换为 JSON 对象,如下所示。

String jsonFormat = JsonFormat.printer().print(data);

根据文档https://developers.google.com/protocol-buffers/docs/proto3#json,我将字节作为 Base64 字符串(例如“hashedStaEthMac”:“QDOMIxG+tTIRi7wlMA9yGtOoJ1g=”, )。但我想得到一个可读的字符串(例如“locAlgorithm”:“ALGORITHM_ESTIMATION”, )。下面是一个示例输出。有没有办法将 JSON 对象作为纯文本或任何解决方法来获取实际值。

{
  "seq": "71811887",
  "timestamp": 1488640438,
  "op": "OP_UPDATE",
  "topicSeq": "9023777",
  "sourceId": "xxxxxxxx",
  "location": {
    "staEthMac": {
      "addr": "xxxxxx"
    },
    "staLocationX": 1148.1763,
    "staLocationY": 980.3377,
    "errorLevel": 588,
    "associated": false,
    "campusId": "n5THo6IINuOSVZ/cTidNVA==",
    "buildingId": "7hY/jVh9NRqqxF6gbqT7Jw==",
    "floorId": "LV/ZiQRQMS2wwKiKTvYNBQ==",
    "hashedStaEthMac": "xxxxxxxxxxx",
    "locAlgorithm": "ALGORITHM_ESTIMATION",
    "unit": "FEET"
  }
}

预期格式如下。

seq: 85264233
timestamp: 1488655098
op: OP_UPDATE
topic_seq: 10955622
source_id: 00505698749E
location {
    sta_eth_mac {
        addr: xx:xx:xx:xx:xx:xx
    }
    sta_location_x: 916.003
    sta_location_y: 580.115
    error_level: 854
    associated: false
    campus_id: 9F94C7A3A20836E392559FDC4E274D54
    building_id: EE163F8D587D351AAAC45EA06EA4FB27
    floor_id: 83144E609EEE3A64BBD22C536A76FF5A
    hashed_sta_eth_mac: 
    loc_algorithm: ALGORITHM_ESTIMATION
    unit: FEET
}

【问题讨论】:

  • 我不明白。 可读的字符串是什么意思?
  • @SotiriosDelimanolis 作为普通文本,例如“locgorithm”:“ALGORITHM_ESTIMATION”,在上述输出中与“hashedStaEthMac”相比:“QDOMIxG+tTIRi7wlMA9yGtOoJ1g=",
  • new String(Base64.getDecoder().decode(jsonFormat), StandardCharsets.UTF_8) 将转换 Base64 字符串。
  • @SotiriosDelimanolis System.out.println(new String(Base64.getDecoder().decode("n5THo6IINuOSVZ/cTidNVA=="), StandardCharsets.UTF_8));正在打印 ??6?U??N'MT。使用 java.util.Base64;

标签: java json protocol-buffers


【解决方案1】:

不容易,因为实际值是二进制的,这就是为什么它们首先是 Base64 编码的。

尝试解码以下值之一:

$ echo -n 'n5THo6IINuOSVZ/cTidNVA==' | base64 -D
??ǣ6?U??N'MT

为了获得更易读的值,你必须了解二进制数据实际上是什么,然后决定要使用什么格式来显示它。

名为 staEthMac.addr 的字段为 6 个字节,可能是以太网 MAC 地址。它通常显示为 xx:xx:xx:xx:xx:xx 其中 xx 是每个字节的十六进制值。因此,您可以将 Base64 字符串解码为 byte[],然后调用函数将每个字节转换为十六进制并用 ':' 分隔它们。

campusId、buildingId 和 floorId 字段为 16 个字节(128 位),可能是 UUID。 UUID 通常显示为 xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx,其中每个 x 是一个十六进制数字(4 位)。因此,您可以(再次)将 Base64 字符串转换为 byte[],然后打印十六进制数字,可选择添加破折号。

不确定 sourceId 和 hashedStaEthMac,但您可以按照转换为 byte[] 并打印为十六进制的模式。本质上,您只是在进行从 base 64 到 base 16 的转换。您最终会得到这样的结果:

$ echo -n 'n5THo6IINuOSVZ/cTidNVA==' | base64 -D | xxd -p
9f94c7a3a20836e392559fdc4e274d54

我不确定你得到的一点是它是二进制数据。没有像“ALGORITHM_ESTIMATION”那样有意义的“可读”版本;你能做的最好的就是用字母和数字对二进制数据进行编码,这样你至少可以发音。

Base64(使用 64 个不同字符对二进制进行编码)发音为“N 5 T H 小写-O 6 ...”,但它并不友好,因为字母大小写很重要,而且它使用像 O 和 I 这样看起来像数字的字母.十六进制(仅使用 16 个字符对二进制进行编码)更易于阅读。

【讨论】:

  • 是否有任何 java 实用程序可以为我做到这一点,或者任何相同的示例代码都会有所帮助。
  • 试用 Apache Commons 编解码器。
  • 试过但没有运气。编码版本为 n5THo6IINuOSVZ/cTidNVA== 解码版本为 Ÿ”Ç£¢6ã'UŸÜN'MT
  • 是的——它仍然是二进制的。然后,您应该使用 Commons Codec Hex 类将输出编码为十六进制。查看更新的答案。
  • 我已经用预期的输出更新了这个问题。我相信这些值是匹配的。
猜你喜欢
  • 2021-12-12
  • 1970-01-01
  • 2014-12-22
  • 1970-01-01
  • 2021-09-23
  • 1970-01-01
  • 2023-04-01
  • 1970-01-01
  • 2012-07-21
相关资源
最近更新 更多