2016-09-25 28 views
10

Swift 2'de dize değişkenlerini genişletmek ve sha1, sha256 ve md5 yapabilmek için aşağıdaki kodu kullandım. hızlı 3'e taşındıktan sonraSwift 3 yapma sha1, sha256 ve md5 işlevleri

, kod artık çalışmıyor! Ben dönüştürmek ancak sürekli hataları girmek çalıştı.

herhangi bir fikir bunu nasıl çözebilir?

extension NSData { 
    func hexString() -> String { 
     var string = String() 
     for i in UnsafeBufferPointer<UInt8>(start: UnsafeMutablePointer<UInt8>(bytes), count: length) { 
      string += Int(i).hexString() 
     } 
     return string 
    } 

    func MD5() -> NSData { 
     let result = NSMutableData(length: Int(CC_MD5_DIGEST_LENGTH))! 
     CC_MD5(bytes, CC_LONG(length), UnsafeMutablePointer<UInt8>(result.mutableBytes)) 
     return NSData(data: result) 
    } 

    func SHA1() -> NSData { 
     let result = NSMutableData(length: Int(CC_SHA1_DIGEST_LENGTH))! 
     CC_SHA1(bytes, CC_LONG(length), UnsafeMutablePointer<UInt8>(result.mutableBytes)) 
     return NSData(data: result) 
    } 

    func SHA256() -> NSData { 
     let result = NSMutableData(length: Int(CC_SHA256_DIGEST_LENGTH)) 
     CC_SHA256(bytes, CC_LONG(length), UnsafeMutablePointer(result!.mutableBytes)) 
     return NSData(data: result!) 
    } 
} 

extension String { 
    func hexString() -> String { 
     return (self as NSString).dataUsingEncoding(NSUTF8StringEncoding)!.hexString() 
    } 

    func MD5() -> String { 
     return (self as NSString).dataUsingEncoding(NSUTF8StringEncoding)!.MD5().hexString() 
    } 

    func SHA1() -> String { 
     return (self as NSString).dataUsingEncoding(NSUTF8StringEncoding)!.SHA1().hexString() 
    } 

    func SHA256() -> String { 
     return (self as NSString).dataUsingEncoding(NSUTF8StringEncoding)!.SHA256().hexString() 
    } 

} 
+0

= "artık çalışma değil"? – user2864740

+0

, hızlı bir şekilde 3 yolla değişiklik yapılması gerektiği anlamına gelir :(( – Hamid

+0

Göçmen denediniz mi (benzemiyor)? – vadian

cevap

15

iyi olur

Data

Swift 3'te Swift Data kullanmayı tercih ediyorum Ve Data ile çalışırken sırasıyla bytes veya mutableBytes kullanıyorlardı, nereye withUnsafeBytes(_:) veya withUnsafeMutableBytes(_:), kullanmak gerekir.

withUnsafeMutableBytes(_:)

extension Data { 
    func hexString() -> String { 
     let string = self.map{Int($0).hexString()}.joined() 
     return string 
    } 

    func MD5() -> Data { 
     var result = Data(count: Int(CC_MD5_DIGEST_LENGTH)) 
     _ = result.withUnsafeMutableBytes {resultPtr in 
      self.withUnsafeBytes {(bytes: UnsafePointer<UInt8>) in 
       CC_MD5(bytes, CC_LONG(count), resultPtr) 
      } 
     } 
     return result 
    } 

    /* 
    ... nearly the same for `SHA1` and `SHA256`. 
    */ 
} 

extension String { 
    func hexString() -> String { 
     return self.data(using: .utf8)!.hexString() 
    } 

    func MD5() -> String { 
     return self.data(using: .utf8)!.MD5().hexString() 
    } 

    /* 
    ... nearly the same for `SHA1` and `SHA256`. 
    */ 
} 

I (göreceli olarak hafif uygulamaları için) no-argüman yöntemlere göre hesaplanmış yapım özellikleri tercih

withUnsafeBytes(_:)

. Sen bunları kullanarak tüm parçaları düzeltmek gerekir, ancak böyle bir şey yazabilirsiniz:

extension Int { 
    var hexString: String { 
     return ... 
    } 
} 
extension Data { 
    var hexString: String { 
     let string = self.map{Int($0).hexString}.joined() 
     return string 
    } 

    var MD5: Data { 
     var result = Data(count: Int(CC_MD5_DIGEST_LENGTH)) 
     _ = result.withUnsafeMutableBytes {resultPtr in 
      self.withUnsafeBytes {(bytes: UnsafePointer<UInt8>) in 
       CC_MD5(bytes, CC_LONG(count), resultPtr) 
      } 
     } 
     return result 
    } 

    /* 
    ... nearly the same for `SHA1` and `SHA256`. 
    */ 
} 

extension String { 
    var hexString: String { 
     return self.data(using: .utf8)!.hexString 
    } 

    var MD5: String { 
     return self.data(using: .utf8)!.MD5.hexString 
    } 

    /* 
    ... nearly the same for `SHA1` and `SHA256`. 
    */ 
} 

Orada NSData kullanarak kodu için daha hızlı bir düzeltme olabilir, ama ben Swift 3 Data geçmek için tavsiye edebilir .

+0

Mükemmel çözüm: 'Int' uzantısı aslında gerekli değildir. '' Data' içinde hexString' basitçe 'self.map {String ($ 0, radix: 16)} ile oluşturulabilir. join() ' – vadian

+0

@vadian, yorumunuz için teşekkürler. Ama kodunuzda' '' dize ($ 0, radix: 16) '' '' dır ('': ''% 02X '', $ 0) '' '' dır. , radix: 16) 'değişken uzunluk üretir String, 1 ... 2 (" 0 "..." FF "). Her bayt olmadan, sabit uzunluğa sahip orijinal bayt dizisini alamazsınız. temsilidir. Uzunluk 2 olabilir, büyük ihtimalle ama zorunlu değildir. Bu yüzden orijinal kodda 'Int' uzantısını kullanmaya devam ettim. – OOPer

+0

'Data' harita fonksiyonunun gövde tipi' UInt8' yani dize uzunluğu her zaman 2 – vadian

0
func MD5() -> String { 

    let length = Int(CC_MD5_DIGEST_LENGTH) 
    var digest = [UInt8](repeating: 0, count: length) 
    if let d = self.data(using: String.Encoding.utf8) { 
     d.withUnsafeBytes { (body: UnsafePointer<UInt8>) in 
      CC_MD5(body, CC_LONG(d.count), &digest) 
     } 
    } 
    return (0..<length).reduce("") { 
     $0 + String(format: "%02x", digest[$1]) 
    } 

} 
0

Cevabın Tamam çoğu bulamaz, ama biz gerçek bir evrensel çözüm olmalıdır eğer biz bir seviye bunu hızlandırmaya gerek.

CC_LONG sadece bir UInt32 olup gerçekten büyük veri yapılarını desteklemeyecektir. kolaylık sağlamak için

struct Sha256 { 
    let context = UnsafeMutablePointer<CC_SHA256_CTX>.allocate(capacity:1) 

    init() { 
     CC_SHA256_Init(context) 
    } 

    func update(data: Data) { 
     data.withUnsafeBytes { (bytes: UnsafePointer<Int8>) -> Void in 
      let end = bytes.advanced(by: data.count) 
      for f in sequence(first: bytes, next: { $0.advanced(by: Int(CC_LONG.max)) }).prefix(while: { (current) -> Bool in current < end}) { 
       _ = CC_SHA256_Update(context, f, CC_LONG(Swift.min(f.distance(to: end), Int(CC_LONG.max)))) 
      } 
     } 
    } 

    func final() -> Data { 
     var digest = [UInt8](repeating: 0, count:Int(CC_SHA256_DIGEST_LENGTH)) 
     CC_SHA256_Final(&digest, context) 

     return Data(bytes: digest) 
    } 
} 

biz Veriler için bir uzantı yapın::

extension Data { 
    func sha256() -> Data { 
     let s = Sha256() 
     s.update(data: self) 
     return s.final() 
    } 
} 
biz Data ile çalışmak bir temel oluşturmak

İlk:

Bu Swift 3benim çözümdür

Ve dize için bir uzantı son:

extension String { 
    func sha256() -> Data { 
     return self.data(using: .utf8)!.sha256() 
    } 
} 

Gerekirse, sonucu kullanım durumuna bağlı olarak altıgen dizgiye veya Data sonucuna dönüştürün.

Bu çözüm, Sha512, MD5 vb. Için, Apple'ın CommonCrypto'yu kullanarak birçok farklı kullanım örneğine genişletmek için gerçek evrensel çözümler elde etmek için kullanılabilir.

0

tamamlanması için, Swift 4 en kısa ve en esnek bir çözüm:

extension Data { 

    var hexString: String { 
     return map { String(format: "%02hhx", $0) }.joined() 
    } 

    var md5: Data { 
     var digest = [Byte](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH)) 
     self.withUnsafeBytes({ 
      _ = CC_MD5($0, CC_LONG(self.count), &digest) 
     }) 
     return Data(bytes: digest) 
    } 

    var sha1: Data { 
     var digest = [UInt8](repeating: 0, count: Int(CC_SHA1_DIGEST_LENGTH)) 
     self.withUnsafeBytes({ 
      _ = CC_SHA1($0, CC_LONG(self.count), &digest) 
     }) 
     return Data(bytes: digest) 
    } 

    var sha256: Data { 
     var digest = [UInt8](repeating: 0, count: Int(CC_SHA256_DIGEST_LENGTH)) 
     self.withUnsafeBytes({ 
      _ = CC_SHA256($0, CC_LONG(self.count), &digest) 
     }) 
     return Data(bytes: digest) 
    } 

} 

extension String { 

    var md5: Data { 
     return self.data(using: .utf8)!.md5 
    } 

    var sha1: Data { 
     return self.data(using: .utf8)!.sha1 
    } 

    var sha256: Data { 
     return self.data(using: .utf8)!.sha256 
    } 

}