将base64字符串转换为十六进制为可读字符串:Swift

时间:2018-03-12 16:48:51

标签: swift string base64 hex

我正在处理一些第三方数据。他们从我们的请求返回的数据被假设为base64编码为字符串。他们提供了将这些指令转换为可读格式的说明:

*首先,使用开源“tomeko”在线工具将Base64字符串转换为十六进制:http://tomeko.net/online_tools/base64.php?lang=en

其次,在SAE J2735标准中,所有消息都作为MessageFrame发送。 MessageFrame包含有关MessageFrame中包含的特定类型消息的信息。解码步骤#1中十六进制的正确方法是在开源Marben在线解码器工具中选择ASN.1消息下的MessageFrame:http://www.marben-products.com/asn.1/services/decoder-asn1-automotive.html。 *

我正在使用iPhone应用程序,因此转移到这些网站进行转换并不是最佳选择。我使用以下代码将B64字符串解码为十六进制:

func convert64EncodedToHex(_ data:Data) -> String {
    return data.map{ String(format: "%02x", $0) }.joined()
}

回来了:

5B224142 4E464141 41414F51 6F414141 63414545 4E427055 476C5141 45434B67 796C6A4C 49414442 44515A2B 686E3641 4341686F 4D77517A 42414251 51304753 675A4B41 41774961 44536F4E 4B674163 454E426D 43475949 41514347 677A7544 4F34225D 

但当我将其插入Marben解码器时,它失败了:

<error>
  <description>Unexpected end of stream reached when decoding</description>
  <nature>fr.marben.asnsdk.japi.InconsistentStructureException</nature>
  <ErrorOffset>72</ErrorOffset>
  <ValuePath>SPAT.intersections.IntersectionState#1.states.MovementState#1.state-time-speed.MovementEvent#1.regional.SEQUENCE#1.regExtValue</ValuePath>
</error>

最终我需要将十六进制解码为应用程序中的可读字符串,所以我想知道:

  1. 为什么我的b64到十六进制代码似乎失败
  2. 如何将十六进制转换为可读字符串
  3. 修改

    好吧,在Marben网站上,我选择了错误的下拉解码。选择MessageFrame提供了一个成功的结果,所以b64到hex我有效。由此产生的新问题是我无法破译这些结果:

    68字节解码。 *解码成功*

1 个答案:

答案 0 :(得分:0)

有几个问题。

  1. 您提供的十六进制字符串转换为原始响应:

      

    [&#34; ABNFAAAAOQoAAAcAEENBpUGlQAECKgyljLIADBDQZ + hn6ACAhoMwQzBABQQ0GSgZKAAwIaDSoNKgAcENBmCGYIAQCGgzuDO4&#34;]

    也许他们是用JSON数组发给你的?最重要的是,在对此进行任何其他操作之前,您需要删除[""]。例如,如果它是JSON,则可以在对其进行base64解码之前解析JSON:

    do {
        let array = try JSONDecoder().decode([String].self, from: originalJSONData)
        if let base64String = array.first {
             // use `base64String` here
        }
    } catch {
        print(error)
    }
    
  2. 如果您想要与该base64字符串关联的数据,您可以执行以下操作:

    let base64String = "ABNFAAAAOQoAAAcAEENBpUGlQAECKgyljLIADBDQZ+hn6ACAhoMwQzBABQQ0GSgZKAAwIaDSoNKgAcENBmCGYIAQCGgzuDO4"
    let payload = Data(base64Encoded: base64String)!
    
  3. 如果您只想将其显示为十六进制字符串(我不确定您为什么要这样做),最简单的方法是:

    print(payload as NSData)
    

    那会显示

      

    &lt; 00134500 0000390a 00000700 104341a5 41a54001 022a0ca5 8cb2000c 10d067e8 67e80080 86833043 30400504 34192819 28003021 a0d2a0d2 a001c10d 06608660 80100868 33b833b8&gt;

  4. 如果你真的需要那个十六进制String表示,你可以使用你的问题中的例程(但是在base64解码的有效载荷而不是base64字符串上):

    let payloadString = payload.map { String(format: "%02x", $0) }
        .joined()
    print(payloadString)
    

    那将返回:

      

    001345000000390a00000700104341a541a54001022a0ca58cb2000c10d067e867e8008086833043304005043419281928003021a0d2a0d2a001c10d066086608010086833b833b8

  5. 就个人而言,如果您想直观地检查二进制有效负载,则十六进制字符串(在步骤3和4中)很有意思,但可能您确实需要原始有效负载(在步骤2中)。当我查看这些数据时,并不是很明显这个&#34;第三方数据&#34;返回,所以我不能进一步评论,但你可能有一些机制来消费这个payload