Come posso codificare una stringa in Base64 in Swift?


115

Voglio convertire una stringa in Base64. Ho trovato risposte in diversi punti, ma non funziona più in Swift. Sto usando Xcode 6.2. Credo che la risposta potrebbe funzionare nelle versioni precedenti di Xcode e non in Xcode 6.2.

Qualcuno potrebbe guidarmi a farlo in Xcode 6.2?

La risposta che ho trovato è stata questa, ma non funziona nella mia versione di Xcode:

var str = "iOS Developer Tips encoded in Base64"
println("Original: \(str)")

// UTF 8 str from original
// NSData! type returned (optional)
let utf8str = str.dataUsingEncoding(NSUTF8StringEncoding)

// Base64 encode UTF 8 string
// fromRaw(0) is equivalent to objc 'base64EncodedStringWithOptions:0'
// Notice the unwrapping given the NSData! optional
// NSString! returned (optional)
let base64Encoded = utf8str.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.fromRaw(0)!)
println("Encoded:  \(base64Encoded)")

// Base64 Decode (go back the other way)
// Notice the unwrapping given the NSString! optional
// NSData returned
let data = NSData(base64EncodedString: base64Encoded, options:   NSDataBase64DecodingOptions.fromRaw(0)!)

// Convert back to a string
let base64Decoded = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Decoded:  \(base64Decoded)")

rif: http://iosdevelopertips.com/swift-code/base64-encode-decode-swift.html


L'estensione rapida è pulita e pratica. stackoverflow.com/a/46969102/1996294
Ashok

Risposte:


69

Non ho 6.2 installato ma non credo che 6.3 sia diverso a questo proposito:

dataUsingEncoding restituisce un opzionale, quindi è necessario scartarlo.

NSDataBase64EncodingOptions.fromRawè stato sostituito con NSDataBase64EncodingOptions(rawValue:). Un po 'sorprendentemente, questo non è un inizializzatore fallibile, quindi non è necessario scartarlo.

Ma poiché NSData(base64EncodedString:) è un inizializzatore non riuscito, è necessario scartarlo.

A proposito, tutte queste modifiche sono state suggerite da Xcode migrator (fare clic sul messaggio di errore nella grondaia e ha un suggerimento "fix-it").

Il codice finale, riscritto per evitare gli scarti forzati, ha questo aspetto:

import Foundation

let str = "iOS Developer Tips encoded in Base64"
println("Original: \(str)")

let utf8str = str.dataUsingEncoding(NSUTF8StringEncoding)

if let base64Encoded = utf8str?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0)) 
{

    println("Encoded:  \(base64Encoded)")

    if let base64Decoded = NSData(base64EncodedString: base64Encoded, options:   NSDataBase64DecodingOptions(rawValue: 0))
                          .map({ NSString(data: $0, encoding: NSUTF8StringEncoding) })
    {
        // Convert back to a string
        println("Decoded:  \(base64Decoded)")
    }
}

(se usi Swift 1.2 potresti usare più if-let invece della mappa)

Aggiornamento Swift 5:

import Foundation

let str = "iOS Developer Tips encoded in Base64"
print("Original: \(str)")

let utf8str = str.data(using: .utf8)

if let base64Encoded = utf8str?.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0)) {
    print("Encoded: \(base64Encoded)")

    if let base64Decoded = Data(base64Encoded: base64Encoded, options: Data.Base64DecodingOptions(rawValue: 0))
    .map({ String(data: $0, encoding: .utf8) }) {
        // Convert back to a string
        print("Decoded: \(base64Decoded ?? "")")
    }
}

3
Non puoi semplicemente fare []invece di NSDataBase64EncodingOptions(rawValue: 0)?
Brimstone

198

veloce

import Foundation

extension String {

    func fromBase64() -> String? {
        guard let data = Data(base64Encoded: self) else {
            return nil
        }

        return String(data: data, encoding: .utf8)
    }

    func toBase64() -> String {
        return Data(self.utf8).base64EncodedString()
    }

}

Questo è in codice sicuro, è necessario gestire gli optional.
Mohammad Zaid Pathan

Aggiunta sintassi Swift 3
Matthew Knippen

3
Ho provato a convertire questa stringa di base 64: dfYcSGpvBqyzvkAXkdbHDA==e l'output previsto doveva essere: u�Hjo���@���ma la funzione sopra restituisce nil. Puoi controllare l'output della stringa in base 64 sopra su questi siti: Site1 , Site2
Chanchal Raj

@ZaidPathan, risolto!
Darkngs

22

Potresti semplicemente fare una semplice estensione come:

import UIKit

// MARK: - Mixed string utils and helpers
extension String {


    /**
    Encode a String to Base64

    :returns: 
    */
    func toBase64()->String{

        let data = self.dataUsingEncoding(NSUTF8StringEncoding)

        return data!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))

    }

}

iOS 7 e versioni successive


20

Swift 4.0.3

import UIKit

extension String {

func fromBase64() -> String? {
    guard let data = Data(base64Encoded: self, options: Data.Base64DecodingOptions(rawValue: 0)) else {
        return nil
    }

    return String(data: data as Data, encoding: String.Encoding.utf8)
}

func toBase64() -> String? {
    guard let data = self.data(using: String.Encoding.utf8) else {
        return nil
    }

    return data.base64EncodedString(options: Data.Base64EncodingOptions(rawValue: 0))
    }
}

Sto usando lo stesso codice ma il compilatore restituisce un errore: il valore del tipo "Dati" non ha membri "base64EncodedStringWithOptions" in Swift 4.0.3
Ashwini Chougale

5
Senza Data(self.utf8).base64EncodedString()alcun optional sarebbe necessario per toBase64 (). Dalla risposta sotto: stackoverflow.com/a/35360697/129202
Jonny

19

Swift 4.2

"abcd1234".data(using: .utf8)?.base64EncodedString()

13

Dopo una ricerca approfondita ho trovato la soluzione

Codifica

    let plainData = (plainString as NSString).dataUsingEncoding(NSUTF8StringEncoding)
    let base64String =plainData.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.fromRaw(0)!)
    println(base64String) // bXkgcGxhbmkgdGV4dA==

decodifica

    let decodedData = NSData(base64EncodedString: base64String, options:NSDataBase64DecodingOptions.fromRaw(0)!)
    let decodedString = NSString(data: decodedData, encoding: NSUTF8StringEncoding)    
    println(decodedString) // my plain data

Altro su questo http://creativecoefficient.net/swift/encoding-and-decoding-base64/


12

Xcode 8.3.2 • Swift 3.1

extension String {
    var data:          Data  { return Data(utf8) }
    var base64Encoded: Data  { return data.base64EncodedData() }
    var base64Decoded: Data? { return Data(base64Encoded: self) }
}

extension Data {
    var string: String? { return String(data: self, encoding: .utf8) }
}

let original = "iOS Developer Tips encoded in Base64"

let utf8Data = original.data                             // 36 bytes
let base64EncodedString = utf8Data.base64EncodedString() //  aU9TIERldmVsb3BlciBUaXBzIGVuY29kZWQgaW4gQmFzZTY0\n"
let base64EncodedData = utf8Data.base64EncodedData()     //  48 bytes"

print("base64EncodedData:", original.base64Encoded)      //  48 bytes
print("base64EncodedString:", original.base64Encoded.string ?? "") // "aU9TIERldmVsb3BlciBUaXBzIGVuY29kZWQgaW4gQmFzZTY0"
print("base64DecodedData:", original.base64Encoded.string?.base64Decoded  ?? "") // 36 bytes
print("base64DecodedString:", original.base64Encoded.string?.base64Decoded?.string ?? "") // iOS Developer Tips encoded in Base64

11

Swift 3 o 4

let base64Encoded = Data("original string".utf8).base64EncodedString()

1
La migliore risposta sulla pagina perché è aggiornata, restituisce un non facoltativo e non racchiude un'operazione così semplice in un'estensione.
Jano

8

Swift 5.1 , Xcode 11 :

public extension String {

    /// Assuming the current string is base64 encoded, this property returns a String
    /// initialized by converting the current string into Unicode characters, encoded to
    /// utf8. If the current string is not base64 encoded, nil is returned instead.
    var base64Decoded: String? {
        guard let base64 = Data(base64Encoded: self) else { return nil }
        let utf8 = String(data: base64, encoding: .utf8)
        return utf8
    }

    /// Returns a base64 representation of the current string, or nil if the
    /// operation fails.
    var base64Encoded: String? {
        let utf8 = self.data(using: .utf8)
        let base64 = utf8?.base64EncodedString()
        return base64
    }

}

Funziona alla grande, è un codice davvero succinto e ha aiutato immensamente.
raddevus

7

Swift 3/4 / 5.1

Ecco una semplice Stringestensione, che consente di preservare gli optional in caso di errore durante la decodifica.

extension String {
    /// Encode a String to Base64
    func toBase64() -> String {
        return Data(self.utf8).base64EncodedString()
    }

    /// Decode a String from Base64. Returns nil if unsuccessful.
    func fromBase64() -> String? {
        guard let data = Data(base64Encoded: self) else { return nil }
        return String(data: data, encoding: .utf8)
    }
}

Esempio:

let testString = "A test string."

let encoded = testString.toBase64() // "QSB0ZXN0IHN0cmluZy4="

guard let decoded = encoded.fromBase64() // "A test string."
    else { return } 

2

Dopo tutta la lotta mi piaceva.

func conversion(str:NSString)
{

    if let decodedData = NSData(base64EncodedString: str as String, options:NSDataBase64DecodingOptions(rawValue: 0)),
        let decodedString = NSString(data: decodedData, encoding: NSUTF8StringEncoding) {

        print(decodedString)//Here we are getting decoded string

Dopo aver chiamato un'altra funzione per convertire la stringa decodificata in dizionario

        self .convertStringToDictionary(decodedString as String)
    }


}//function close

// per la stringa nel dizionario

func convertStringToDictionary(text: String) -> [String:AnyObject]? {
    if let data = text.dataUsingEncoding(NSUTF8StringEncoding) {
        do {
            let json = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String:AnyObject]

            print(json)
            if let stack = json!["cid"]  //getting key value here
            {
                customerID = stack as! String
                print(customerID)
            }

        } catch let error as NSError {
            print(error)
        }
    }
    return nil
}

2

PER SWIFT 3.0

let str = "iOS Developer Tips encoded in Base64"
print("Original: \(str)")

let utf8str = str.data(using: String.Encoding.utf8)

if let base64Encoded = utf8str?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
{

  print("Encoded:  \(base64Encoded)")

  if let base64Decoded = NSData(base64Encoded: base64Encoded, options:   NSData.Base64DecodingOptions(rawValue: 0))
    .map({ NSString(data: $0 as Data, encoding: String.Encoding.utf8.rawValue) })
  {
    // Convert back to a string
    print("Decoded:  \(base64Decoded)!")
  }
}

Mi restituisce sempre zero. Puoi per favore aiutare.
Pawan

1

Swift 4.2

var base64String = "my fancy string".data(using: .utf8, allowLossyConversion: false)?.base64EncodedString()

per decodificare, vedere (da https://gist.github.com/stinger/a8a0381a57b4ac530dd029458273f31a )

//: # Swift 3: Base64 encoding and decoding
import Foundation

extension String {
//: ### Base64 encoding a string
    func base64Encoded() -> String? {
        if let data = self.data(using: .utf8) {
            return data.base64EncodedString()
        }
        return nil
    }

//: ### Base64 decoding a string
    func base64Decoded() -> String? {
        if let data = Data(base64Encoded: self) {
            return String(data: data, encoding: .utf8)
        }
        return nil
    }
}
var str = "Hello, playground"
print("Original string: \"\(str)\"")

if let base64Str = str.base64Encoded() {
    print("Base64 encoded string: \"\(base64Str)\"")
    if let trs = base64Str.base64Decoded() {
        print("Base64 decoded string: \"\(trs)\"")
        print("Check if base64 decoded string equals the original string: \(str == trs)")
    }
}

0

SwiftyBase64 (full disclosure: l'ho scritto io) è una codifica Swift Base64 nativa (nessuna libreria di decodifica. Con essa, puoi codificare Base64 standard:

let bytesToEncode : [UInt8] = [1,2,3]
let base64EncodedString = SwiftyBase64.EncodeString(bytesToEncode)

o URL e nome file Safe Base64:

let bytesToEncode : [UInt8] = [1,2,3]
let base64EncodedString = SwiftyBase64.EncodeString(bytesToEncode, alphabet:.URLAndFilenameSafe)

0

@ Risposta di Airspeed Velocity in Swift 2.0:

let str = "iOS Developer Tips encoded in Base64"
print("Original: \(str)")
let base64Encoded = str.dataUsingEncoding(NSUTF8StringEncoding)!.base64EncodedStringWithOptions([])
print("Encoded: \(base64Encoded)")
let base64DecodedData = NSData(base64EncodedString: base64Encoded, options: [])!
var base64DecodedString = String(data: base64DecodedData, encoding: NSUTF8StringEncoding)!
print("Decoded: \(base64DecodedString)")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.