2

Is it possible to correctly decode using Swift language base64 encoded string which contains a string in non-utf8 encoding (ie. Windows-1252 or ISO-8859-1)?

Every snippet of code that can be found here on stackoverflow fails and return nil.

For example let decodedData = NSData(base64EncodedString: base64String, options:NSDataBase64DecodingOptions.IgnoreUnknownCharacters)

gives empty as it ignores bad characters and if I don't use this option it gives nil like dozens of other gist code

This is test base64 string containing part of cryptographic key which I need to decode. If I use some other language like Python, PHP or Java it is decoding correctly but using Swift I can't do that.

FkXKDAAAAAAAAAAAvMBAYFk1JADmiwHAz+rNFy93faklHL7MW3Hhlf1Bo7/hpZ3j1GmdySyIpJ4YlRH65mleumYqsgUgYLlQY/jQq2YykMPUwZQ4jTgU7Q== should be EʼÀ@`Y5$æ‹ÀÏêÍ/w}©%¾Ì[qá•ýA£¿á¥ãÔiÉ,ˆ¤ž•úæi^ºf*² `¹PcøÐ«f2ÃÔÁ”88í

as it can be decoded with online tool like this

Here is another one:

FgdhDAAAAAAABwAAOJAiYMxlJQAMbwHAWrYq59+po4WdMS4R+EHV4hBKzWn8oZYpTFdFQ33usZUa19d+umkWcL2g4mmVeUOwUG2dZGWIrxlTWJA+s/RTTQ==

Please advise is there any way to decode base64 strings like this locally on iOS device or I really need to send it to server to do that?

moogeek
  • 397
  • 4
  • 14
  • 34
  • What exactly are you trying to do? What is the base 64 encoded data supposed to contain? It is certainly not a string. If you are trying to convert it into a string, you are going down the wrong route. Please describe the bigger context. Otherwise it will not be possible to help you. – Codo Mar 04 '21 at 22:03

2 Answers2

4

You're looking a fairly old examples. The syntax changed to this:

let decodedData = Data(base64Encoded: base64String)

I've tested with your examples, and they work fine. Keep in mind that the output is raw Data, this isn't a String in any encoding (Windows-1252 or ISO-8859-1, etc). It's just a sequence of random bytes, and that's what it is expected to be. The online tool you're using is just trying to decode it as ISO-8859-1, but that's gibberish, and is in fact corrupted in the output you've shown. It's not displaying the first byte (which is 0x16, and unprintable).

Rob Napier
  • 286,113
  • 34
  • 456
  • 610
  • Thanks for pointing me to the right way. But I'm still stuck with converting this Data object to correct string. The bad news is that I exactly don't know which encoding is used when the base64 string was encoded. The next thing I want to do with decoded string is concatenate it with other part of key and then generate PDF417 image barcode using `CIPDF417BarcodeGenerator` of `CIFilter`. Here is how I try to convert decoded string: `let decodedKey = String(data: decodedData!, encoding: .ascii) ` <- dunno what encoding I really need to use – moogeek Mar 04 '21 at 20:32
  • The first Base64 encoding you provided isn't any kind of string. What you say it should be isn't what that Base64 encodes. You say the first character should be `E`, but it's really `\u{16}` (which is unprintable). As you say, it's a cryptographic key, which you shouldn't expect to decode to any printable string. – Rob Napier Mar 04 '21 at 21:05
  • If you're trying to turn this into something to be barcode scanned, you need to turn arbitrary data into ASCII. The tool for that is Base64. You have that already, just don't decode the Base64. (This is why Base64 exists.) – Rob Napier Mar 04 '21 at 21:18
  • Thanks that's getting clear for me. But can I concatenate this decoded data with other string? For example append "abc" to the end of it or prepend. If I do this like that: ` ` `let anotherStr='abc' let decodedData = Data(base64Encoded: base64String) let decodedKey = String(data: decodedData!, encoding: .ascii) let concatenatedStr = "\(anotherStr)\(decodedKey)" ``` – moogeek Mar 05 '21 at 13:15
  • and provide the result to barcode generate function which is making convertion to ascii again ```let data = string.data(using: String.Encoding.ascii)``` I receive malformed UIMage. In backtrace resulted string looks like this ```abc\u{16}\aa\u{c}\0\0\0\0\0\a\0\08\u{90}\"`Ìe%\0\u{c}o\u{1}ÀZ¶*çß©£\u{85}\u{9d}1.\u{11}øAÕâ\u{10}JÍiü¡\u{96})LWEC}î±\u{95}\u{1a}××~ºi\u{16}p½ âi\u{95}yC°Pm\u{9d}de\u{88}¯\u{19}SX\u{90}>³ôSM``` – moogeek Mar 05 '21 at 13:21
  • You're still decoding the base64 in this. Don't do that. Base64 is a string encoding already. To the question, you can make all kinds of strings, but it depends on what you want the reader to do with this information. If you just stick extra characters before or after Base64, you're going to corrupt it and the reader won't be able to decode it. You'd need to provide some kind of separator (like `:`, which isn't a Base64 character), or promise a specific length. – Rob Napier Mar 05 '21 at 13:46
  • I have asked another question which covers all my problem https://stackoverflow.com/questions/66506428/pdf417-decode-and-generate-the-same-barcode-using-swift – moogeek Mar 06 '21 at 14:15
-1

In my case, server returns a url safe base64 string, whitch can be decoded successfully in android or other platform, I replace '-' with '+' and '_' with '/', then add additional '=' at the end to make sure string.length is divisible by 4.

  • 1
    As it’s currently written, your answer is unclear. Please [edit] to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jul 22 '23 at 17:22