【问题标题】:How can I encode a string to Base64 in Swift?如何在 Swift 中将字符串编码为 Base64?
【发布时间】:2015-06-04 14:04:07
【问题描述】:

我想将字符串转换为 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)")

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

【问题讨论】:

标签: swift base64


【解决方案1】:

斯威夫特

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

}

【讨论】:

  • 这是安全代码,你需要处理可选的。
  • 添加了 Swift 3 语法
  • 我尝试转换这个 base 64 字符串:dfYcSGpvBqyzvkAXkdbHDA==,预期输出必须是:u�Hjo���@���,但上面的函数返回 nil。您可以在这些站点上查看上述 base-64 字符串的输出:Site1Site2
  • @ZaidPathan,已修复!
【解决方案2】:

我没有安装 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 ?? "")")
    }
}

【讨论】:

  • 你不能只用[]而不是NSDataBase64EncodingOptions(rawValue: 0)吗?
  • 是的,你可以;我刚刚测试了它。 [] 是默认值,所以你可以不传入任何参数直接调用函数:utf8str?.base64EncodedString()
【解决方案3】:

斯威夫特 4.2

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

【讨论】:

    【解决方案4】:

    你可以做一个简单的扩展,比如:

    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 及更高版本

    【讨论】:

      【解决方案5】:

      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 中没有成员“base64EncodedStringWithOptions”
      • 使用Data(self.utf8).base64EncodedString() 时,toBase64() 将不需要任何选项。从下面的答案:stackoverflow.com/a/35360697/129202
      【解决方案6】:

      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
      

      【讨论】:

        【解决方案7】:

        经过深入研究,我找到了解决方案

        编码

            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/

        【讨论】:

          【解决方案8】:

          Swift 3 或 4

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

          【讨论】:

          • 页面上的最佳答案,因为它已更新,返回非可选值,并且不会将如此简单的操作包装在扩展中。
          【解决方案9】:

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

          【讨论】:

          • 这很好用,代码真的很简洁,帮助很大。
          【解决方案10】:

          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 } 
          

          【讨论】:

            【解决方案11】:

            经过所有的努力,我还是这样做了。

            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
            

            在我调用另一个将解码字符串转换为字典的函数之后

                    self .convertStringToDictionary(decodedString as String)
                }
            
            
            }//function close
            

            //字符串转字典

            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
            }
            

            【讨论】:

              【解决方案12】:

              适用于 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)!")
                }
              }
              

              【讨论】:

              • 它总是返回零。你能帮忙吗?
              【解决方案13】:

              斯威夫特 4.2

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

              要解码,请参阅(来自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)")
                  }
              }
              

              【讨论】:

                【解决方案14】:

                SwiftyBase64(完全公开:我写的)是原生 Swift Base64 编码(没有解码库。有了它,你可以编码标准 Base64:

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

                或 URL 和文件名 Safe Base64:

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

                【讨论】:

                  【解决方案15】:

                  @Airspeed Velocity 在 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)")
                  

                  【讨论】:

                    猜你喜欢
                    • 2010-09-19
                    • 1970-01-01
                    • 2021-07-24
                    • 2012-01-19
                    • 2022-11-09
                    • 1970-01-01
                    • 2014-12-03
                    • 1970-01-01
                    相关资源
                    最近更新 更多