PruitIgoe
PruitIgoe

Reputation: 6384

Converting base64 string to hex to readable string: Swift

I am working with some 3rd party data. The data they are returning from our request is suppose to be base64 encoded into a string. They provide these instructions for converting it to a readable format:

*First, converting the Base64 string to hexadecimals using the open-source "tomeko" online tool: http://tomeko.net/online_tools/base64.php?lang=en.

Second, in the SAE J2735 standard, all messages are sent as a MessageFrame. The MessageFrame contains information about which particular type of message is included within the MessageFrame. The proper way to decode the hexadecimals from step #1, is to select MessageFrame under the ASN.1 message in the open-source Marben online decoder tool: http://www.marben-products.com/asn.1/services/decoder-asn1-automotive.html. *

I'm working on an iPhone app so reaching out to these sites for the conversion is not optimal. I decoded the B64 string into hex with this code:

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

which came back as so:

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 

But when I plug that into the Marben decoder it fails:

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

Eventually I would need to decode the hex into readable string in the app so I was wondering:

  1. Why my b64 to hex code seems to be failing
  2. how to transform hex to readable string

EDIT

OK, on the Marben site I was selecting the wrong drop down for decoding. Selecting MessageFrame provided a successful result so the b64 to hex I have is working. New problem arose from that is I can't decipher these results:


68 bytes decoded. * DECODING SUCCESSFUL *

Upvotes: 2

Views: 2380

Answers (1)

Rob
Rob

Reputation: 437432

A couple of problems.

  1. The hex string you provided translates to an original response of:

    ["ABNFAAAAOQoAAAcAEENBpUGlQAECKgyljLIADBDQZ+hn6ACAhoMwQzBABQQ0GSgZKAAwIaDSoNKgAcENBmCGYIAQCGgzuDO4"]

    Perhaps they sent it to you in a JSON array? Bottom line, you need to trim out the [" and "] before you do anything else with this. For example, if it was JSON, you could parse the JSON before you base64-decode it:

    do {
        let array = try JSONDecoder().decode([String].self, from: originalJSONData)
        if let base64String = array.first {
             // use `base64String` here
        }
    } catch {
        print(error)
    }
    
  2. If you want the data associated with that base64 string, you'd do something like:

    let base64String = "ABNFAAAAOQoAAAcAEENBpUGlQAECKgyljLIADBDQZ+hn6ACAhoMwQzBABQQ0GSgZKAAwIaDSoNKgAcENBmCGYIAQCGgzuDO4"
    let payload = Data(base64Encoded: base64String)!
    
  3. If you merely want to display that as a hex string (I'm not sure why you'd want to do that), the easiest way is:

    print(payload as NSData)
    

    That would display

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

  4. If you really need that hex String representation, you can use the routine you have in your question (but do it on the base64-decoded payload, rather than the base64 string):

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

    That will return:

    001345000000390a00000700104341a541a54001022a0ca58cb2000c10d067e867e8008086833043304005043419281928003021a0d2a0d2a001c10d066086608010086833b833b8

Personally, the hex strings (in step 3 and 4) are interesting if you want to visually examine the binary payload, but probably you really need the original payload (in step 2). As I look at this data, it's not immediately obvious what this "3rd party data" returned, so I cannot comment further on that, but you presumably have some mechanism to consume this payload.

Upvotes: 1

Related Questions