★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤微信公衆號:山青詠芝(shanqingyongzhi)
➤博客園地址:山青詠芝(https://www.cnblogs.com/strengthen/)
➤GitHub地址:https://github.com/strengthen/LeetCode
➤原文地址:http://www.javashuo.com/article/p-sxfahcow-mb.html
➤若是連接不是山青詠芝的博客園地址,則多是爬取做者的文章。
➤原文已修改更新!強烈建議點擊原文地址閱讀!支持做者!支持原創!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★html
目錄:[Swift]通天遁地Swiftgit
本文將演示如何編寫原生的3DES加密和解密程序。github
首先建立一個橋接頭文件,由於須要使用到OC語言的通用加密解密類庫。算法
在項目文件夾【DemoApp】上點擊鼠標右鍵,彈出右鍵菜單。swift
【New File】->【Header File】->【Next】->緩存
【Save As】:Header.h->【Create】安全
在該文件中,添加須要引用到的框架。微信
1 //添加須要引用到的框架。 2 #ifndef Header_h 3 #define Header_h 4 5 #import <CommonCrypto/CommonCrypto.h> 6 #import "SecurityUtil.h" 7 8 #endif /* Header_h */
點擊項目名稱【DemoApp】,顯示項目的屬性信息,app
將頭文件添加到橋接頭選項中->【Build Settings】框架
->在搜索框內,輸入須要定位的設置項目的名稱:【Objective-C Bridging Hader】
->鼠標雙擊選項右側【Objective-C Bridging Hader】,彈出橋接頭文件設置窗口。
->在打開的輸入窗口中,輸入剛剛建立的頭文件的相對路徑:【DemoApp/Header.h】
在項目導航區,打開視圖控制器的代碼文件【ViewController.swift】
如今開始編寫代碼,實現3DES的加密和解密功能。
1 import UIKit 2 3 //首先建立一個集合,用來生成隨機的公用的密鑰 4 private let randomStringArray: [Character] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789".map({$0}) 5 6 class ViewController: UIViewController { 7 8 //給類添加一個字符串屬性, 9 //做爲加密解密的公鑰和私鑰, 10 //並對其進行初始化操做。 11 var key:String = "" 12 13 override func viewDidLoad() { 14 super.viewDidLoad() 15 // Do any additional setup after loading the view, typically from a nib. 16 //調用方法 17 encrypt(encryptData: "https://www.cnblogs.com/strengthen/") 18 } 19 20 //添加一個方法,用來生成指定長度的字符串 21 func randomStringOfLength(_ length:Int) -> String 22 { 23 //初始化一個字符串變量 24 var string = "" 25 //添加一個指定次數的循環語句 26 ////往字符串變量中添加隨機的字符 27 for _ in (1...length) 28 { 29 //從集合中得到英文大小寫字母和0~9之間的隨機數字, 30 //並將隨機字符添加到字符串中。 31 string.append(randomStringArray[Int(arc4random_uniform(UInt32(randomStringArray.count) - 1))]) 32 } 33 //返回生成的隨機字符串 34 return string 35 } 36 37 //添加一個方法,對字符串參數進行加密 38 func encrypt(encryptData:String) 39 { 40 //生成一個隨機的字符串,做爲加密解密的密鑰。 41 //其參數的值是24, 42 //所以這裏將生成一個長度爲24的,包含英文大小寫字母和數字的隨機字符串。 43 key = randomStringOfLength(kCCKeySize3DES) 44 //將待加密的字符串,轉換成指定編碼的數據類型。 45 let inputData : Data = encryptData.data(using: String.Encoding.utf8)! 46 //將隨機字符串的密鑰,一樣轉換成數據類型。 47 let keyData: Data = key.data(using: String.Encoding.utf8, allowLossyConversion: false)! 48 //建立一個非安全的可變原始指針, 49 //在建立該指針時,向系統申請了個數爲密鑰字節數的內存。 50 let keyBytes = UnsafeMutableRawPointer(mutating: (keyData as NSData).bytes) 51 //建立一個常量,表示密鑰的長度,它的值是24 52 let keyLength = size_t(kCCKeySize3DES) 53 //得到待加密的數據類型對象的長度。 54 let dataLength = Int(inputData.count) 55 //建立一個非安全的指針,並從系統中分配相應的內存,做爲加密的輸入緩存。 56 let dataBytes = UnsafeRawPointer((inputData as NSData).bytes) 57 //建立一個指定長度的可變二進制數據對象, 58 //該對象做爲加密的輸出緩存,用來存儲加密後的數據。 59 //其長度爲輸入緩存的長度和塊大小的和,塊的大小爲8。 60 let bufferData = NSMutableData(length: Int(dataLength) + kCCBlockSize3DES)! 61 //建立一個非安全的可變指針,並根據輸出緩存的大小,分配相應的內存。 62 let bufferPointer = UnsafeMutableRawPointer(bufferData.mutableBytes) 63 //得到輸出緩存的長度。 64 let bufferLength = size_t(bufferData.length) 65 //建立一個變量,用來存儲加密後的輸出緩存的最終字節數。 66 var bytesDecrypted = Int(0) 67 68 //調用來自頭文件中的加密解密方法, 69 //參數1:用來區分加密或解密,這裏選擇加密 70 //參數2:加密的算法 71 //參數3:使用密鑰和算法,對文本進行加密時的方法。 72 let cryptStatus = CCCrypt(UInt32(kCCEncrypt), UInt32(kCCAlgorithm3DES), 73 UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding), 74 keyBytes, keyLength, nil, dataBytes, dataLength, 75 bufferPointer, bufferLength, &bytesDecrypted) 76 77 //當執行完加密方法後,會返回一個狀態,經過對狀態的檢測, 78 //能夠判斷加密操做是否成功, 79 //加密操做有可能返回七種狀態。 80 if Int32(cryptStatus) == Int32(kCCSuccess) 81 { 82 //當判斷加密操做正確後,設置輸出數據的長度, 83 //以調整輸出緩存的大小。爲最終輸出的加密數據的長度。 84 bufferData.length = bytesDecrypted 85 86 //在控制檯輸出日誌 87 print(bufferData) 88 //對加密後的數據進行解密。 89 decrypt(inputData: bufferData as Data) 90 } 91 else 92 { 93 print("Error:\(cryptStatus)") 94 } 95 } 96 97 //添加一個方法,用來實現指定類型的解密操做。 98 //解密的代碼和加密的代碼大體相同 99 func decrypt(inputData : Data) 100 { 101 //將做爲隨機字符串的密鑰,轉換成數據類型 102 let keyData: Data = key.data(using: String.Encoding.utf8, allowLossyConversion: false)! 103 //建立一個非安全的可變原始指針, 104 //在建立該指針時,向系統申請了個數爲密鑰字節數的內存。 105 let keyBytes = UnsafeMutableRawPointer(mutating: (keyData as NSData).bytes) 106 //建立一個常量,表示密鑰的長度,它的值是 24 107 let keyLength = size_t(kCCKeySize3DES) 108 //得到待加密數據類型對象的長度 109 let dataLength = Int(inputData.count) 110 //建立一個非安全的指針,並從系統中分配相應的內存,做爲解密的輸入緩存。 111 let dataBytes = UnsafeRawPointer((inputData as NSData).bytes) 112 //建立一個指定長度的可變二進制數據對象, 113 //該對象做爲解密的輸出緩存,用來存儲解密後的數據。 114 //其長度爲輸入緩存的長度和塊大小的和,塊的大小爲8。 115 let bufferData = NSMutableData(length: Int(dataLength) + kCCBlockSize3DES)! 116 //建立一個非安全的可變指針,並根據輸出緩存的大小,分配相應的內存。 117 let bufferPointer = UnsafeMutableRawPointer(bufferData.mutableBytes) 118 //得到輸出緩存的長度 119 let bufferLength = size_t(bufferData.length) 120 //建立一個變量,用來存儲解密後的輸出緩存的最終字節數。 121 var bytesDecrypted = Int(0) 122 123 //調用來自頭文件中的加密解密方法, 124 //參數1:用來區分加密或解密,這裏選擇解密 125 //參數2:解密的算法 126 //參數3:使用密鑰和算法,對文本進行解密時的方法。 127 let cryptStatus = CCCrypt(UInt32(kCCDecrypt), UInt32(kCCAlgorithm3DES), 128 UInt32(kCCOptionECBMode + kCCOptionPKCS7Padding), 129 keyBytes, keyLength, nil, dataBytes, dataLength, 130 bufferPointer, bufferLength, &bytesDecrypted) 131 132 //當執行完加密方法後,會返回一個狀態,經過對狀態的檢測, 133 //能夠判斷解密操做是否成功, 134 if Int32(cryptStatus) == Int32(kCCSuccess) 135 { 136 //當判斷解密操做正確後,設置輸出數據的長度, 137 //以調整輸出緩存的大小。爲最終輸出的解密數據的長度。 138 bufferData.length = bytesDecrypted 139 140 //將解密後的數據,以指定的編碼方式,轉換成字符串對象。 141 let clearDataAsString = NSString(data: bufferData as Data, encoding: String.Encoding.utf8.rawValue) 142 //打印日誌 143 print("The result:\(clearDataAsString! as String)") 144 } 145 else 146 { 147 //打印日誌 148 print("Error in crypto operation:\(cryptStatus)") 149 } 150 } 151 152 override func didReceiveMemoryWarning() { 153 super.didReceiveMemoryWarning() 154 // Dispose of any resources that can be recreated. 155 } 156 }