在Swift中,我该如何对字符串进行Base64编码/解码?

166
我想将一个字符串转换为Base64。我在几个地方找到了答案,但在Swift中不再起作用。我正在使用Xcode 6.2。我相信这个答案可能适用于之前的Xcode版本,而不适用于Xcode 6.2。
请问有人可以指导我如何在Xcode 6.2中做到这一点吗?
我找到的答案是这样的,但在我的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)")

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

Swift扩展非常干净和方便。https://dev59.com/PFwZ5IYBdhLWcg3wGs_D#46969102 - Ashok
17个回答

279

Swift

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

}

这是安全代码,你需要处理可选项。 - Mohammad Zaid Pathan
增加了Swift 3的语法。 - Matthew Knippen
5
我试图将这个 base 64 字符串 dfYcSGpvBqyzvkAXkdbHDA== 进行转换,期望的输出应该是: u�Hjo���@���,但是上面的函数返回了 nil。你可以在这些网站上检查上述 base-64 字符串的输出: Site1, Site2 - Chanchal Raj
@ZaidPathan,已修复! - Darkngs

104

我没有安装6.2版本,但我认为在这方面6.3版本没有任何不同:

dataUsingEncoding 返回一个可选值,所以你需要解包它。

NSDataBase64EncodingOptions.fromRaw 已经被替换成了 NSDataBase64EncodingOptions(rawValue:)。有点意外的是,这不是一个可失败的初始化器,所以你不需要对其进行解包操作。

但由于 NSData(base64EncodedString:) 是一个可失败的初始化器,因此你需要对其进行解包操作。

顺便说一句,所有这些更改都是由Xcode迁移器建议的。(单击窗口边栏中的错误消息,它会有一个“修复”建议)。

最终代码已重写,避免使用强制解包操作,看起来像这样:

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

(如果使用 Swift 1.2,你可以使用多个 if-let 代替 map)

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
你能否只使用 [] 而不是 NSDataBase64EncodingOptions(rawValue: 0) - brimstone
1
可以的,我刚刚测试过了。[]是默认值,所以您可以直接调用函数而不传递任何参数:utf8str?.base64EncodedString() - Peter Schorn

31

Swift 4.2

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

28

Xcode 11.4 • Swift 5.2或更高版本

extension StringProtocol {
    var data: Data { Data(utf8) }
    var base64Encoded: Data { data.base64EncodedData() }
    var base64Decoded: Data? { Data(base64Encoded: string) }
}

extension LosslessStringConvertible {
    var string: String { .init(self) }
}

extension Sequence where Element == UInt8 {
    var data: Data { .init(self) }
    var base64Decoded: Data? { Data(base64Encoded: data) }
    var string: String? { String(bytes: 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.base64Decoded?.string ?? "") // iOS Developer Tips encoded in Base64

23

你可以通过一个简单的扩展来实现:

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及以上版本


21

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

我正在使用相同的代码,但编译器仍然报错:在Swift 4.0.3中,类型“Data”没有成员“base64EncodedStringWithOptions”。 - Ashwini Chougale
5
使用 Data(self.utf8).base64EncodedString(),在调用 toBase64() 时不需要使用可选型。参考以下回答:https://dev59.com/EF0b5IYBdhLWcg3wSPqL#35360697 - Jonny

14

经过彻底的研究,我找到了解决方案。

编码

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

解码

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

更多关于此内容,请访问http://creativecoefficient.net/swift/encoding-and-decoding-base64/


14

Swift 3或4

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

1
这是页面上最佳答案,因为它被更新了,返回一个非可选的结果,并且没有将如此简单的操作包装在一个扩展中。 - Jano

14

Swift 5.1Xcode 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
    }

}

这个非常好用,代码简洁明了,帮助很大。 - raddevus
无需从base64Encoded返回可选项。您可以简单地返回Data(utf8).base64EncodedString() - Leo Dabus

9

Swift 3 / 4 / 5.1

这里有一个简单的String扩展,允许在解码时保留可选项以防出现错误。

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

例子:

let testString = "A test string."

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

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接