Comment encoder une chaîne en Base64 dans Swift?


115

Je veux convertir une chaîne en Base64. J'ai trouvé des réponses à plusieurs endroits, mais cela ne fonctionne plus dans Swift. J'utilise Xcode 6.2. Je pense que la réponse pourrait être un travail dans les versions précédentes de Xcode et non dans Xcode 6.2.

Quelqu'un pourrait-il s'il vous plaît me guider pour faire cela dans Xcode 6.2?

La réponse que j'ai trouvée était la suivante, mais cela ne fonctionne pas dans ma version de 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)")

réf: http://iosdevelopertips.com/swift-code/base64-encode-decode-swift.html


L'extension Swift est propre et pratique. stackoverflow.com/a/46969102/1996294
Ashok

Réponses:


69

Je n'ai pas installé 6.2 mais je ne pense pas que 6.3 soit différent à cet égard:

dataUsingEncoding renvoie un optionnel, vous devez donc le déballer.

NSDataBase64EncodingOptions.fromRawa été remplacé par NSDataBase64EncodingOptions(rawValue:). Légèrement surprenant, ce n'est pas un initialiseur disponible, vous n'avez donc pas besoin de le déballer.

Mais comme il NSData(base64EncodedString:) s'agit d' un initialiseur disponible, vous devez le déballer.

Btw, tous ces changements ont été suggérés par Xcode Migrator (cliquez sur le message d'erreur dans la gouttière et il a une suggestion de «correction»).

Le code final, réécrit pour éviter le déballage forcé, ressemble à ceci:

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)")
    }
}

(si vous utilisez Swift 1.2, vous pouvez utiliser plusieurs if-let au lieu de la carte)

Mise à jour de 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
Tu ne peux pas faire juste à la []place NSDataBase64EncodingOptions(rawValue: 0)?
brimstone

199

Rapide

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()
    }

}

Ceci est en code sécurisé, vous devez gérer les options.
Mohammad Zaid Pathan

Syntaxe Swift 3 ajoutée
Matthew Knippen

3
J'ai essayé de convertir cette chaîne de base 64: dfYcSGpvBqyzvkAXkdbHDA==et la sortie attendue devait être: u�Hjo���@���mais la fonction ci-dessus renvoie nil. Vous pouvez vérifier la sortie de la chaîne de base 64 ci-dessus sur ces sites: Site1 , Site2
Chanchal Raj

@ZaidPathan, corrigé!
Darkngs

23

Vous pouvez simplement faire une simple extension comme:

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


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

J'utilise le même code mais quand même, le complicateur donne une erreur: la valeur de type 'Data' n'a pas de membre 'base64EncodedStringWithOptions' dans Swift 4.0.3
Ashwini Chougale

5
Sans Data(self.utf8).base64EncodedString()option serait nécessaire pour toBase64 (). De ci-dessous, réponse: stackoverflow.com/a/35360697/129202
Jonny

19

Swift 4.2

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

13

Après des recherches approfondies, j'ai trouvé la solution

Codage

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

Décodage

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

En savoir plus sur 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 ou 4

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

1
Meilleure réponse sur la page car elle est mise à jour, renvoie une opération non facultative et n'enveloppe pas une opération aussi simple dans une extension.
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
    }

}

Cela fonctionne très bien, est un code vraiment succinct et a énormément aidé.
raddevus

7

Swift 3/4 / 5.1

Voici une Stringextension simple , permettant de conserver les options en cas d'erreur lors du décodage.

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

Exemple:

let testString = "A test string."

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

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

2

Après toute lutte, j'ai fait comme ça.

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

Après avoir appelé une autre fonction pour convertir une chaîne décodée en dictionnaire

        self .convertStringToDictionary(decodedString as String)
    }


}//function close

// pour la chaîne au dictionnaire

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

POUR 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)!")
  }
}

Cela me rend toujours nul. Peux-tu aider s'il te plait.
Pawan

1

Swift 4.2

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

pour décoder, voir (de 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 (divulgation complète: je l'ai écrit) est un encodage natif Swift Base64 (pas de bibliothèque de décodage. Avec lui, vous pouvez encoder la norme Base64:

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

ou URL et nom de fichier Safe Base64:

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

0

Réponse @Airspeed Velocity dans 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)")
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.