any md5 swift

2019-07-18 16:14:16 weixin_38735568 阅读数 285
  • 子查询(any、some)

    能熟练使用sql语句对数据库进行增删改查 理解sql注入原理,注重sql安全 熟练使用数据库的几大对象存储过程、存储函数、视图、 触发器等

    0人学习 赵晓希
    免费试看

仿view.snp.xxx的调用形式

先看调用效果:“123456”.yy_Str.MD5ForLower32Bate()

"123456".yy_Str.MD5ForLower32Bate()
//类似:view.snp.xxx

为什么要这么做呢?好处在哪呢?

  1. 降低耦合度:传统的写法,直接在类别中添加一个方法或属性例如:
extension String {
    ///验证身份证号
    func validateidnum() -> Bool {
        let idRegex = "^(\\d{14}|\\d{17})(\\d|[xX])$"
        let idTest:NSPredicate = NSPredicate(format: "SELF MATCHES %@", idRegex)
        return idTest.evaluate(with: self)
    }
}
  1. 降低不必要的冲突:当另一个工程师也有类似的需求时,他也新建文件写啦同样的方法,这就会有冲突,然后排查…
  2. 只需要一个属性,就能实现想要的扩展功能,代码简洁

如何实现

定义协议:YProtocolExtension.swift

//协议扩展
protocol YExtensionProtocol {
    associatedtype YExtensionType //给谁写扩展例如:UIView、String、UIButton
    var value: YExtensionType { get }
}
  1. 定义一个实现该协议的结构体
struct YExtensionKitStructTypeEncodable<T>: YExtensionProtocol {
///实现协议的属性
    var value: T
    typealias YExtensionType = T //指定类型(传入泛型)
    /// 构造方法
    init(kit: T) {
        self.value = kit
    }
}
  1. 同样我们也可以直接指定类型
struct YExtensionStringEncodable: YExtensionProtocol {
///实现协议的属性
    var value: String
    typealias YExtensionType = String //指定类型
    /// 构造方法
    init(kit: String) {
        self.value = kit
    }
}
  1. 扩展YExtensionProtocol,实现相关String中MD5加密的功能

注意:凡是协议中定义的函数自己在协议中实现啦,他就是可选的类型,反之,是继承协议着必须实现。

String为例:MD5加密

import CommonCrypto

//MARK:String-MD5加密32位
//where YExtensionType == String 指定YExtensionType:为那种类型
extension YExtensionProtocol where YExtensionType == String {
    ///MD5加密32位小写
    func MD5ForLower32Bate() -> String {
        let str = value.cString(using: .utf8)
        let strLen = CUnsignedInt(value.lengthOfBytes(using: .utf8))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
        CC_MD5(str!, strLen, result)
        let hash = NSMutableString.init()
        for i in 0..<digestLen {
            hash.appendFormat("%02x", result[i])
        }
        result.deinitialize(count: digestLen)
        return String(hash)
    }
    ///MD5加密32位大写
    func MD5ForUpper32Bate() -> String {
        let str = value.cString(using: .utf8)
        let strLen = CUnsignedInt(value.lengthOfBytes(using: .utf8))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        
        let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
        CC_MD5(str!, strLen, result)
        let hash = NSMutableString()
        for i in 0..<digestLen {
            hash.appendFormat("%02X", result[i])
        }
        result.deinitialize(count: digestLen)
        return String(hash)
    }
}
  1. 给String新增扩展:添加属性
//MARKL:有关字符串的扩展
extension String {
///第一种:直接指定类型的
    var yy_Str: YExtensionStringEncodable {
        return YExtensionStringEncodable.init(kit: self)
    }
    ///第二种:泛型传递
    var yy_kit: YExtensionKitStructTypeEncodable<String> {
        return YExtensionKitStructTypeEncodable.init(kit: self)
    }
}
  1. 在ViewController测试结果如下
override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        print("123456".yy_kit.MD5ForLower32Bate())
        print("123456".yy_kit.MD5ForUpper32Bate())
        print("——————————————————————————————————")
        print("123456".yy_Str.MD5ForLower32Bate())
        print("123456".yy_Str.MD5ForUpper32Bate())
    }
// 输出结果如下:
e10adc3949ba59abbe56e057f20f883e
E10ADC3949BA59ABBE56E057F20F883E
——————————————————————————————————
e10adc3949ba59abbe56e057f20f883e
E10ADC3949BA59ABBE56E057F20F883E

核心完整代码如下

//
//  YExtensionProtocol.swift
//  YExtentionDemo
//
//  Created by bruce yao on 2019/7/18.
//  Copyright © 2019 bruce yao. All rights reserved.
//
import Foundation
import UIKit
import CommonCrypto

//协议扩展
protocol YExtensionProtocol {
    associatedtype YExtensionType
    var value: YExtensionType { get }
}
///Struct类型的扩展基础
struct YExtensionKitStructTypeEncodable<T>: YExtensionProtocol {
    var value: T
    typealias YExtensionType = T
    /// 构造方法
    init(kit: T) {
        self.value = kit
    }
}
struct YExtensionStringEncodable: YExtensionProtocol {
    ///实现协议的属性
    var value: String
    typealias YExtensionType = String //指定类型(传入泛型)
    /// 构造方法
    init(kit: String) {
        self.value = kit
    }
}
/////Class类型的扩展基础
//final class YExtensionKitClassTypeEncodable<T>: YExtensionProtocol {
//    /// 泛型
//    var value: T
//    typealias YExtensionType = T
//    /// 构造方法
//    init(kit: T) {
//        self.value = kit
//    }
//}
//MARK:String-MD5加密32位
extension YExtensionProtocol where YExtensionType == String {
    ///MD5加密32位小写
    func MD5ForLower32Bate() -> String {
        let str = value.cString(using: .utf8)
        let strLen = CUnsignedInt(value.lengthOfBytes(using: .utf8))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
        CC_MD5(str!, strLen, result)
        let hash = NSMutableString.init()
        for i in 0..<digestLen {
            hash.appendFormat("%02x", result[i])
        }
        result.deinitialize(count: digestLen)
        return String(hash)
    }
    ///MD5加密32位大写
    func MD5ForUpper32Bate() -> String {
        let str = value.cString(using: .utf8)
        let strLen = CUnsignedInt(value.lengthOfBytes(using: .utf8))
        let digestLen = Int(CC_MD5_DIGEST_LENGTH)
        
        let result = UnsafeMutablePointer<CUnsignedChar>.allocate(capacity: digestLen)
        CC_MD5(str!, strLen, result)
        let hash = NSMutableString()
        for i in 0..<digestLen {
            hash.appendFormat("%02X", result[i])
        }
        result.deinitialize(count: digestLen)
        return String(hash)
    }
}

//MARK:有关字符串的扩展
extension String {
    var yy_Str: YExtensionStringEncodable {
        return YExtensionStringEncodable.init(kit: self)
    }
    var yy_kit: YExtensionKitStructTypeEncodable<String> {
        return YExtensionKitStructTypeEncodable.init(kit: self)
    }
}

Swift 5.0协议扩展 Cocoapods下载

链接:https://github.com/YaoChengZhen/YYExtentions.git

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'

target 'TargetName' do
pod 'YYExtentions', 
end
2014-11-20 10:35:00 weixin_30457465 阅读数 7
  • 子查询(any、some)

    能熟练使用sql语句对数据库进行增删改查 理解sql注入原理,注重sql安全 熟练使用数据库的几大对象存储过程、存储函数、视图、 触发器等

    0人学习 赵晓希
    免费试看

引入OC类库

md5.h:

 

#import <UIKit/UIKit.h>

 

@interface Md5Controller : UIViewController

 

@end

 

md5.m:

#import "Md5Controller.h"

 

@interface Md5Controller ()

 

@end

 

@implementation Md5Controller

 

- (void)viewDidLoad {

    [super viewDidLoad];

    // Do any additional setup after loading the view.

}

 

- (void)didReceiveMemoryWarning {

    [super didReceiveMemoryWarning];

    // Dispose of any resources that can be recreated.

}

 

/*

#pragma mark - Navigation

 

// In a storyboard-based application, you will often want to do a little preparation before navigation

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    // Get the new view controller using [segue destinationViewController].

    // Pass the selected object to the new view controller.

}

*/

 

@end

桥接文件:

 

#import <CommonCrypto/CommonCrypto.h>

 

 

可以直接加在文件里面:

 

extension String {

    func md5() -> String! {

        let str = self.cStringUsingEncoding(NSUTF8StringEncoding)

        let strLen = CUnsignedInt(self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding))

        let digestLen = Int(CC_MD5_DIGEST_LENGTH)

        let result = UnsafeMutablePointer<CUnsignedChar>.alloc(digestLen)

        

        CC_MD5(str!, strLen, result)

        

        var hash = NSMutableString()

        for i in 0..<digestLen {

            hash.appendFormat("%02x", result[i])

        }

        

        result.destroy()

        

        return String(format: hash)

    }

}

 

打印测试:

 

        println("hello".md5())

 

转载于:https://www.cnblogs.com/already/p/4110019.html

2016-10-19 02:16:47 wletv 阅读数 605
  • 子查询(any、some)

    能熟练使用sql语句对数据库进行增删改查 理解sql注入原理,注重sql安全 熟练使用数据库的几大对象存储过程、存储函数、视图、 触发器等

    0人学习 赵晓希
    免费试看

AnyHashable is new structure in Swift 3

AnyHashable
https://developer.apple.com/reference/swift/anyhashable

unannotated NSDictionaries will be imported as [AnyHashable : Any].
https://github.com/apple/swift-evolution/blob/master/proposals/0131-anyhashable.md

2018-01-08 17:10:26 loveqcx123 阅读数 7763
  • 子查询(any、some)

    能熟练使用sql语句对数据库进行增删改查 理解sql注入原理,注重sql安全 熟练使用数据库的几大对象存储过程、存储函数、视图、 触发器等

    0人学习 赵晓希
    免费试看

swift在4.0之前,一直没有一套数据解析的方法。现在4.0后,终于有了Codable可以直接将json转成对象,有望取代OC的KVC机制。
先来看看Codable

public typealias Codable = Decodable & Encodable 

基本使用

它和NSCoding很像,可以重写decoder和encoder。基本的使用很简单

class Person: Codable {
      var name : String = ""
      var age : Int = 0
}

//json字符串
let JSONString = "{"name":"xiaoming","age":10}"
guard let jsonData = JSONString.data(using: .utf8) else {
        return
}
let decoder = JSONDecoder()
guard let obj = try? decoder.decode(Person.self, from: jsonData) else {
        return
}
print(obj.name) //xiaoming
print(obj.age)  //10

CodingKey

说到Codable就离不开CodingKey ,上面的例子只能适用于json数据与model属性一一对应的情况下使用,且对应的key也要一致才可以,而CodingKey可以解决开发中经常遇到的后台给与的key与app不一样的情况

class Person: Codable {
      var name : String = ""
      var age : Int = 0

      enum CodingKeys : String, CodingKey {
            case name = "name_a"
            case age
        }
}

//json字符串
let JSONString = "{"name_a":"xiaoming","age":10}"
guard let jsonData = JSONString.data(using: .utf8) else {
        return
}
let decoder = JSONDecoder()
guard let obj = try? decoder.decode(Person.self, from: jsonData) else {
        return
}
print(obj.name) //xiaoming

同时,如果遇到部分数据不需要接收的情况,CodingKey也可以处理,主要在CodingKeys的枚举中不要写这个key就可以了

class Person: Codable {
      var name : String = ""
      var age : Int = 0
      var score : Double = 0.00

      enum CodingKeys : String, CodingKey {
            case name = "name_a"
            case age
        }
}

//json字符串
let JSONString = "{"name_a":"xiaoming","age":10,"score":98.5}"
guard let jsonData = JSONString.data(using: .utf8) else {
        return
}
let decoder = JSONDecoder()
guard let obj = try? decoder.decode(Person.self, from: jsonData) else {
        return
}
print(obj.score) //0.00

封装

基于Codable的机制,可以简单封装一下,用于项目中。现在常见的网络框架,会直接把json数据转成字典,因此增加了字典转json和json转字典的方法。

//
//  Custom.swift
//  映射反射
//
//  Created by qiuchengxiang@gmail.com on 2018/1/3.
//  Copyright © 2018年 Zillion Fortune. All rights reserved.
//

import Foundation

fileprivate enum MapError: Error {
    case jsonToModelFail    //json转model失败
    case jsonToDataFail     //json转data失败
    case dictToJsonFail     //字典转json失败
    case jsonToArrFail      //json转数组失败
    case modelToJsonFail    //model转json失败
}

protocol Mappable: Codable {
    func modelMapFinished()
    mutating func structMapFinished()
}

extension Mappable {

    func modelMapFinished() {}

    mutating func structMapFinished() {}

    //模型转字典
    func reflectToDict() -> [String:Any] {
        let mirro = Mirror(reflecting: self)
        var dict = [String:Any]()
        for case let (key?, value) in mirro.children {
            dict[key] = value
        }
        return dict
    }


    //字典转模型
    static func mapFromDict<T : Mappable>(_ dict : [String:Any], _ type:T.Type) throws -> T {
        guard let JSONString = dict.toJSONString() else {
            print(MapError.dictToJsonFail)
            throw MapError.dictToJsonFail
        }
        guard let jsonData = JSONString.data(using: .utf8) else {
            print(MapError.jsonToDataFail)
            throw MapError.jsonToDataFail
        }
        let decoder = JSONDecoder()

        if let obj = try? decoder.decode(type, from: jsonData) {
            var vobj = obj
            let mirro = Mirror(reflecting: vobj)
            if mirro.displayStyle == Mirror.DisplayStyle.struct {
                vobj.structMapFinished()
            }
            if mirro.displayStyle == Mirror.DisplayStyle.class {
                vobj.modelMapFinished()
            }
            return vobj
        }
        print(MapError.jsonToModelFail)
        throw MapError.jsonToModelFail
    }


    //JSON转模型
    static func mapFromJson<T : Mappable>(_ JSONString : String, _ type:T.Type) throws -> T {
        guard let jsonData = JSONString.data(using: .utf8) else {
            print(MapError.jsonToDataFail)
            throw MapError.jsonToDataFail
        }
        let decoder = JSONDecoder()
        if let obj = try? decoder.decode(type, from: jsonData) {
            return obj
        }
        print(MapError.jsonToModelFail)
        throw MapError.jsonToModelFail
    }


    //模型转json字符串
    func toJSONString() throws -> String {
        if let str = self.reflectToDict().toJSONString() {
            return str
        }
        print(MapError.modelToJsonFail)
        throw MapError.modelToJsonFail
    }
}


extension Array {

    func toJSONString() -> String? {
        if (!JSONSerialization.isValidJSONObject(self)) {
            print("dict转json失败")
            return nil
        }
        if let newData : Data = try? JSONSerialization.data(withJSONObject: self, options: []) {
            let JSONString = NSString(data:newData as Data,encoding: String.Encoding.utf8.rawValue)
            return JSONString as String? ?? nil
        }
        print("dict转json失败")
        return nil
    }

    func mapFromJson<T : Decodable>(_ type:[T].Type) throws -> Array<T> {
        guard let JSONString = self.toJSONString() else {
            print(MapError.dictToJsonFail)
            throw MapError.dictToJsonFail
        }
        guard let jsonData = JSONString.data(using: .utf8) else {
            print(MapError.jsonToDataFail)
            throw MapError.jsonToDataFail
        }
        let decoder = JSONDecoder()
        if let obj = try? decoder.decode(type, from: jsonData) {
            return obj
        }
        print(MapError.jsonToArrFail)
        throw MapError.jsonToArrFail
    }
}


extension Dictionary {
    func toJSONString() -> String? {
        if (!JSONSerialization.isValidJSONObject(self)) {
            print("dict转json失败")
            return nil
        }
        if let newData : Data = try? JSONSerialization.data(withJSONObject: self, options: []) {
            let JSONString = NSString(data:newData as Data,encoding: String.Encoding.utf8.rawValue)
            return JSONString as String? ?? nil
        }
        print("dict转json失败")
        return nil
    }
}


extension String {
    func toDict() -> [String:Any]? {
        guard let jsonData:Data = self.data(using: .utf8) else {
            print("json转dict失败")
            return nil
        }
        if let dict = try? JSONSerialization.jsonObject(with: jsonData, options: .mutableContainers) {
            return dict as? [String : Any] ?? ["":""]
        }
        print("json转dict失败")
        return nil
    }
}

使用

enum BeerStyle : String, Codable {
    case ipa
    case stout
    case kolsch
    // ...
}



struct Beers: Mappable {

    var arrs : [Beer]
    var name : String

    mutating func structMapFinished() {
        name = "ngdgdfg"
    }

    struct Beer: Mappable {

        var name: String = "fsdf"
        var brewery: String = "fsdfsdf"
        var style: BeerStyle = .ipa
        var score: Double = 0.00
        var p: Person?



        enum CodingKeys : String, CodingKey {
            case name = "name_a"
            case brewery
            case p
            case score
        }


        class Person: Mappable {
            var name : String = ""
            var age : Int = 0
        }

    }
}


let dict1 = ["name_a":"nckjs","brewery":"gdfge","style":"stout","score":60.3,"p":["name":"jokh","age":10]] as [String : Any]
        let dict2 = ["name_a":"nckjs","brewery":"gdfge","style":"stout","score":60.3,"p":["name":"jokh","age":10]] as [String : Any]
        let dict3 = ["name_a":"nckjs","brewery":"gdfge","style":"stout","score":60.3,"p":["name":"jokh","age":10]] as [String : Any]

let arr = [dict1,dict2,dict3]
let dict4 = ["arrs" : arr, "name":"fgsdfs"] as [String : Any]
if let beers = try? Beers.mapFromDict(dict4, Beers.self) {
            print(beers)
}

这里增加了map完成后的回调方法,因为Codable的解析,并不是重新对象属性的set方法,和OC的KVC原理不一样。所以,在做一些赋值完成后的操作,需要使用这个回调方法。同时,需要注意区分class和struct的类型,选择对应的方法

null的处理

因为有人留言,问到后台可能每个值都会返回null的情况,又不想把属性设为可选的,所以增加了对null的处理,如果遇到null,就需要重新init(from decoder: Decoder) throws的方法

class Person: Codable {
            var name : String = ""
            var age : Int = 0

            init() {

            }

            required init(from decoder: Decoder) throws {
                let container = try decoder.container(keyedBy: CodingKeys.self)
                age = try container.decodeNil(forKey: .age) ? 10 : try container.decode(Int.self, forKey: .age)
                name = try container.decode(String.self, forKey: .name)
            }
        }

        let p = Person()
        let str = "{\"name\":\"fdfgdf\",\"age\":null}"
        let jsonData = str.data(using: .utf8)

        let decoder = JSONDecoder()

        if let obj = try? decoder.decode(Person.self, from: jsonData!) {
            print(obj.name,obj.age)
        }else {
            print("解析失败")
        }

decodeNil(forKey key: KeyedDecodingContainer.Key) throws -> Bool
这个方法就是判断在解析时,对应的属性是否是null值,如果是会返回true,如果不是null就会返回false

以上封装基本可以在一些中小型项目中使用,因为swift是一门强类型语言,使用时要注意json数据的类型要和model属性的类型一一对应,否则会解析失败。

参考:http://www.cocoachina.com/swift/20170630/19691.html

demo:https://github.com/NickQCX/CXMap/blob/master/README.md

2017-03-15 15:45:47 fzhlee 阅读数 6665
  • 子查询(any、some)

    能熟练使用sql语句对数据库进行增删改查 理解sql注入原理,注重sql安全 熟练使用数据库的几大对象存储过程、存储函数、视图、 触发器等

    0人学习 赵晓希
    免费试看

       在大多数的iOS开发者看来,采用沙箱机制的iOS系统是很安全的,但事实上,iOS系统及里面的应用并没有想象中那么安全。和安卓应用相似,iOS应用也面临着被破解的威胁,存在大量内购破解、源代码破解、植入病毒或广告、二次打包等情况。

       这就需要对应用程序中进进出出的数据进行加密处理,以保护用户的数据和隐私。那么可以通过加密保护哪些数据呢?

  • 对设备中存储的内容进行加密:开发者经常使用UserDefaults、plist文件、CoreData框架等作为数据存储的载体。在存入数据之前对数据进行一些加密操作,可以增强数据的安全性。
  • 对网络传输的数据进行加密:大部分的iOS应用都需要联网,通过和服务器端进行通信,获得最新的信息并且将内容展现给用户。由于网络传输过程中有可能经过不安全的中间节点,所以应该对敏感数据加密,以保证用户信息的安全。
  • 对账户密码进行加盐操作:加盐Salt在密码学中是指,通过在密码任意固定位置插入特定的字符串,让散列后的结果和使用原始密码的散列结果不相符,这个过程称之为加盐。加盐后的账户密码再经过诸如MD5等方式的加密,然后与服务器端采用同样加盐和加密的密码进行比较,如果两个密码相同,则密码匹配成功。这样无论在客户端还是服务器,当传输的密码被截获后,即使解密成功也无法还原出原始的密码。

对称加密和非对称加密

       加密技术是利用一些技术手段,把重要的数据变为乱码进行数据的传送,当到达目的地后,再用相同或不同的手段进行解密和还原。

       对数据加密的技术分为两类,即对称加密(私人密钥加密)和非对称加密(公开密钥加密)。对称加密以Data Encryption Standard数据加密标准算法即DES为典型代表,非对称加密通常以RivestShamir Adleman即RSA算法为代表。

       对称加密采用对称密码编码技术,它的特点是对数据加密和解密使用相同的密钥,即加密密钥也可以用作解密密钥,这种方法在密码学中叫作对称加密算法,其具有简单快捷、密钥较短、破译困难等特点,如图1所示。

图1

       与对称加密算法不同,非对称加密算法需要两个密钥,一个是公有密钥(Public key),另一个是私有密钥 (Private key)。如果使用公有密钥对数据进行加密,只有用对应的私有密钥才能解密;如果用私有密钥对数据进行加密,那么只有用对应的公有密钥才能解密。因为加密和解密使用的是两个不同的密钥,所以这种算法叫作非对称加密算法,如图2所示:
图2

MD5加密

       MD5的全称是MessageDigest Algorithm 5,即消息摘要算法第五版,是计算机安全领域广泛使用的一种散列函数,用以提供消息的完整性保护。在90年代初由MIT Laboratory for Computer Science 和RSA Data Security Inc的Ronald L.Rivest开发,经MD2、MD3和MD4发展而来。

       MD5可以将任意长度的字节串变换成一个128bit的大整数,并且它是一个不可逆的字符串变换算法,换句话说就是,即使你看到源程序和算法描述,也无法将一个MD5的值变换回原始的字符串。

       MD5的典型应用场景是对一段信息生成指纹,以检测信息是否被篡改。例如将一段文字写在一个文本文件中,并对这个文本文件生成一个MD5的值。然后在对该文件进行传播的过程中,如果其它人修改了文件中的任意内容,当对修改后的文件重新计算MD5时,就会发现新旧两个文件的MD5值是不相同。所以我们经常使用MD5对下载的软件进行校验,以检验软件是否被第三方植入病毒代码或广告代码。


1、创建项目并建立桥接文件

       接着我们来创建一个示例项目,对一个字符串进行MD5加密。首先创建一个基于[Single View Applicaton]模板的空白项目,然后在左侧的项目名称文件夹上点击鼠标右键,并选择右键菜单中的[New File...]选项,创建一个桥接头文件,这是因为我们需要使用到Object-C的CommonCrypto.h。

       完成桥接头文件的创建之后,再使用与上一个示例相同的方式,对桥接头文件的路径进行设置,从而完成项目的配置工作,如图3所示:


图3

       然后继续在左侧的项目名称文件夹上点击鼠标右键,并选择右键菜单中的[New File...]选项,从而创建一个.swift文件,我们将在该文件中对String进行扩展:

//
//  StringMD5.swift
//  SecurityProjectMd5
//
//  Created by Jerry on 2017/1/10.
//  Copyright © 2017 www.coolketang.com. All rights reserved.
//

import Foundation

extension Int
{
    func hexedString() -> String
    {
        return NSString(format:"%02x", self) as String
    }
}

extension NSData
{
    func hexedString() -> String
    {
        var string = String()
        let unsafePointer = bytes.assumingMemoryBound(to: UInt8.self)
        for i in UnsafeBufferPointer<UInt8>(start:unsafePointer, count: length)
        {
            string += Int(i).hexedString()
        }
        return string
    }
    func MD5() -> NSData
    {
        let result = NSMutableData(length: Int(CC_MD5_DIGEST_LENGTH))!
        let unsafePointer = result.mutableBytes.assumingMemoryBound(to: UInt8.self)
        CC_MD5(bytes, CC_LONG(length), UnsafeMutablePointer<UInt8>(unsafePointer))
        return NSData(data: result as Data)
    }
}

extension String
{
    func MD5() -> String
    {
        let data = (self as NSString).data(using: String.Encoding.utf8.rawValue)! as NSData
        return data.MD5().hexedString()
    }
}

       从代码中可以看出MD5加密和SHA1加密的步骤基本相似。不同之处是在第16行的代码中,给NSData添加了一个名为MD5的扩展方式,用来实现数据的MD5加密。在加密过程中,首先创建一个CC_MD5_DIGEST_LENGTH长度的可变数据对象。接着通过CC_MD5方法,对数据进行加密,并将加密后的数据存储于可变数据对象。最后将结果转换为NSData格式并返回。

       在第24行的代码中,对String类进行扩展,并添加一个名为MD5的扩展方法。当调用该方法时,首先将字符串转换为NSData对象,并采用UTF-8的编码方式。接着调用NSData的两个扩展方法,完成对字符串的加密操作,并返回十六进制的结果。


2、修改viewDidLoad方法

       和使用SHA1算法进行加密的示例项目相同,最后一步也是修改ViewController类的viewDidLoad方法,在该方法中对字符串coolketang.com进行MD5加密操作,并在日志区输出加密后的结果,以及密文的长度信息:

//
//  ViewController.swift
//  24.1.2SecurityProject_MD5
//
//  Created by Jerry on 2017/1/10.
//  Copyright © 2017 www.coolketang.com. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        let message = "coolketang.com"
        print("Result:"+message.MD5())
        print("Length:\(message.MD5().lengthOfBytes(using: String.Encoding.utf8))")
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}


现在已经完成了所有的MD5加密功能的编码工作,点击Xcode界面左上角的[编译并运行]按钮  ,打开模拟器运行项目。项目运行后,将弹出一个空白的模拟器,并在日志区输出加密后的结果,如图4所示:


图4





新 作

iOS开发中的神兵利器

共140节课程,讲解GitHub中近百个过千star的iOS热门开源项目
市面上唯一大规模讲解GitHub中热门的iOS开源项目的教程
快速、优雅地解决iOS开发工作中遇到的各种棘手问题

视频观看地址:http://study.163.com/course/courseMain.htm?courseId=1003657013

互动教程下载地址:https://itunes.apple.com/cn/app/id1209739676





sqlite.swift应用简介

阅读数 818

swift @objc dynamic

阅读数 81