3

I have been trying to implement GMAIL API in my application that is built using swift 5 and xcode. I have successfully retrieved the emails from the user but I am unable to get the actual text from the encoded string. Whenever I try to convert this base64 encoded data to Normal string, it returns nil.

Here is the string

WW91ciBhY2NvdW50IHNhbG1hbm1hamlkMTRAZ21haWwuY29tIGlzIGxpc3RlZCBhcyB0aGUgcmVjb3ZlcnkgZW1haWwgZm9yDQpzaWRyYWlicmFoaW0wMzQ5QGdtYWlsLmNvbS4gRG9uJ3QgcmVjb2duaXplIHRoaXMgYWNjb3VudD8gQ2xpY2sgaGVyZQ0KPGh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9BY2NvdW50RGlzYXZvdz9hZHQ9QU9YOGtpcHBKRG5OX19KVGloejdoUHRnMlFwRHRRb3VETWVUalRMN2J4YjA3b2dJRC1xYm54QnZPRElTUjB3Q1h6RHlYQSZyZm49MTI3JmFuZXhwPWdpdmFiLWZhLS1tZHYyLWZhPg0KR29vZ2xlIEFQSXMgRXhwbG9yZXIgd2FzIGdyYW50ZWQgYWNjZXNzIHRvIHlvdXIgbGlua2VkIEdvb2dsZSBBY2NvdW50DQoNCg0Kc2lkcmFpYnJhaGltMDM0OUBnbWFpbC5jb20NCg0KSWYgeW91IGRpZCBub3QgZ3JhbnQgYWNjZXNzLCB5b3Ugc2hvdWxkIGNoZWNrIHRoaXMgYWN0aXZpdHkgYW5kIHNlY3VyZSB5b3VyDQphY2NvdW50Lg0KQ2hlY2sgYWN0aXZpdHkNCjxodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20vQWNjb3VudENob29zZXI_RW1haWw9c2lkcmFpYnJhaGltMDM0OUBnbWFpbC5jb20mY29udGludWU9aHR0cHM6Ly9teWFjY291bnQuZ29vZ2xlLmNvbS9hbGVydC9udC8xNTY3ODQ3ODEyMDAwP3JmbiUzRDEyNyUyNnJmbmMlM0QxJTI2ZWlkJTNELTE1NzQzMDEyNjk4Mjg2MTM3OTQlMjZldCUzRDElMjZhbmV4cCUzRGdpdmFiLWZhLS1tZHYyLWZhPg0KWW91IHJlY2VpdmVkIHRoaXMgZW1haWwgdG8gbGV0IHlvdSBrbm93IGFib3V0IGltcG9ydGFudCBjaGFuZ2VzIHRvIHlvdXINCkdvb2dsZSBBY2NvdW50IGFuZCBzZXJ2aWNlcy4NCsKpIDIwMTkgR29vZ2xlIExMQywgMTYwMCBBbXBoaXRoZWF0cmUgUGFya3dheSwgTW91bnRhaW4gVmlldywgQ0EgOTQwNDMsIFVTQQ0K

Some answers at stackoverflow suggested to add padding to string but that didn't work either.

I have tried all the solutions here but none worked. I have this code implemented right now.

extension String {

    func base64Encoded() -> String? {
        return data(using: .utf8)?.base64EncodedString()
    }

    func base64Decoded() -> String? {
        var st = self;
        print(st.count)
        let remainder = self.count % 4
        if remainder > 0 {
            st = self.padding(toLength: self.count + 4 - remainder,
                                          withPad: "=",
                                          startingAt: 0)
        }

        print(st.count)
        guard let d = Data(base64Encoded: st, options: .ignoreUnknownCharacters) else{
            return nil
        }
        return String(data: d, encoding: .utf8)
    }   
}

But this is not working. I would really appreciate if someone can figure out the issue.

1 Answer 1

6

Your string contains underscore character ('_' U+005F LOW LINE), which is invalid as Base-64.

There are some variations of Base-64, so you need to find which one your Gmail something is using. (Wikipedia Base-64.)

Assuming it uses base64url URL- and filename-safe, you may need to write something like this:

extension String {
    func urlSafeBase64Decoded() -> String? {
        var st = self
            .replacingOccurrences(of: "_", with: "/")
            .replacingOccurrences(of: "-", with: "+")
        let remainder = self.count % 4
        if remainder > 0 {
            st = self.padding(toLength: self.count + 4 - remainder,
                              withPad: "=",
                              startingAt: 0)
        }
        guard let d = Data(base64Encoded: st, options: .ignoreUnknownCharacters) else{
            return nil
        }
        return String(data: d, encoding: .utf8)
    }
}

Example:

let base64 = "WW91ciBhY2NvdW50IHNhbG1hbm1hamlkMTRAZ21haWwuY29tIGlzIGxpc3RlZCBhcyB0aGUgcmVjb3ZlcnkgZW1haWwgZm9yDQpzaWRyYWlicmFoaW0wMzQ5QGdtYWlsLmNvbS4gRG9uJ3QgcmVjb2duaXplIHRoaXMgYWNjb3VudD8gQ2xpY2sgaGVyZQ0KPGh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9BY2NvdW50RGlzYXZvdz9hZHQ9QU9YOGtpcHBKRG5OX19KVGloejdoUHRnMlFwRHRRb3VETWVUalRMN2J4YjA3b2dJRC1xYm54QnZPRElTUjB3Q1h6RHlYQSZyZm49MTI3JmFuZXhwPWdpdmFiLWZhLS1tZHYyLWZhPg0KR29vZ2xlIEFQSXMgRXhwbG9yZXIgd2FzIGdyYW50ZWQgYWNjZXNzIHRvIHlvdXIgbGlua2VkIEdvb2dsZSBBY2NvdW50DQoNCg0Kc2lkcmFpYnJhaGltMDM0OUBnbWFpbC5jb20NCg0KSWYgeW91IGRpZCBub3QgZ3JhbnQgYWNjZXNzLCB5b3Ugc2hvdWxkIGNoZWNrIHRoaXMgYWN0aXZpdHkgYW5kIHNlY3VyZSB5b3VyDQphY2NvdW50Lg0KQ2hlY2sgYWN0aXZpdHkNCjxodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20vQWNjb3VudENob29zZXI_RW1haWw9c2lkcmFpYnJhaGltMDM0OUBnbWFpbC5jb20mY29udGludWU9aHR0cHM6Ly9teWFjY291bnQuZ29vZ2xlLmNvbS9hbGVydC9udC8xNTY3ODQ3ODEyMDAwP3JmbiUzRDEyNyUyNnJmbmMlM0QxJTI2ZWlkJTNELTE1NzQzMDEyNjk4Mjg2MTM3OTQlMjZldCUzRDElMjZhbmV4cCUzRGdpdmFiLWZhLS1tZHYyLWZhPg0KWW91IHJlY2VpdmVkIHRoaXMgZW1haWwgdG8gbGV0IHlvdSBrbm93IGFib3V0IGltcG9ydGFudCBjaGFuZ2VzIHRvIHlvdXINCkdvb2dsZSBBY2NvdW50IGFuZCBzZXJ2aWNlcy4NCsKpIDIwMTkgR29vZ2xlIExMQywgMTYwMCBBbXBoaXRoZWF0cmUgUGFya3dheSwgTW91bnRhaW4gVmlldywgQ0EgOTQwNDMsIFVTQQ0K"

print(base64.urlSafeBase64Decoded() ?? "* decoding failed*")

Output:

You received this email to let you know about important changes to your
Google Account and services.
© 2019 Google LLC, 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA
Sign up to request clarification or add additional context in comments.

1 Comment

That works amazingly. Thanks. I put 4-5 hours in this and started to wonder that if this is some type other encrypted string.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.