String+Extension.swift 4.01 KB
//
//  String+Extension.swift
//  metaCode
//
//  Created by zx on 2023/10/16.
//


import UIKit
import CommonCrypto

extension String {
    //比较两个版本号 //.orderedDescending前者version1版本更大 //.orderedAscending前者版本更小 //.orderedSame版本相等
    func compareVersion(_ version2: String) -> ComparisonResult {
        let v1Components = self.components(separatedBy: ".")
        let v2Components = version2.components(separatedBy: ".")
        let maxLength = max(v1Components.count, v2Components.count)
        
        for i in 0..<maxLength {
            // 处理空位补 0
            let v1 = i < v1Components.count ? (Int(v1Components[i]) ?? 0) : 0
            let v2 = i < v2Components.count ? (Int(v2Components[i]) ?? 0) : 0
            
            if v1 > v2 {
                return .orderedDescending // 当前版本更大
            } else if v1 < v2 {
                return .orderedAscending  // 当前版本更小
            }
        }
        return .orderedSame // 版本相等
    }
    
    
    /// Calculate text's height from `width` and `front`.
    func calculateHeightWith(width: CGFloat, font: UIFont)-> CGFloat {
        let attr = [NSAttributedString.Key.font: font]
        let maxSize: CGSize = CGSize(width: width, height: CGFloat(MAXFLOAT))
        let option = NSStringDrawingOptions.usesLineFragmentOrigin
        return self.boundingRect(with: (maxSize), options: option, attributes: attr, context: nil).size.height
    }
    
    //截取子字符串,eg "123456" start:2为第三位,length:3为长度是3,substring:345
    func subString(start: Int, length: Int) -> String {
        let startIndex = self.index(self.startIndex, offsetBy: start)
        let endIndex = self.index(startIndex, offsetBy: length)
        let substring = self[startIndex..<endIndex]
        return String(substring)
    }
    
    //DES加密
    func crypt(operation:CCOperation, key: String) -> String? {
            
            if let keyData = key.data(using: .utf8) {
                
                var cryptData: Data?
                
                if operation == kCCEncrypt {
                    cryptData = self.data(using: .utf8)
                } else {
                    cryptData = Data(base64Encoded: self, options: .ignoreUnknownCharacters)
                }
                
                if cryptData == nil {
                    return nil
                }
                
                let algoritm: CCAlgorithm = CCAlgorithm(kCCAlgorithmDES)
                let option: CCOptions = CCOptions(kCCOptionPKCS7Padding)
                
                let keyBytes = [UInt8](keyData)
                let keyLength = kCCKeySizeDES
                
                let dataIn = [UInt8](cryptData!)
                let dataInlength = cryptData!.count
                
                let dataOutAvailable = Int(dataInlength + kCCBlockSizeDES)
                let dataOut = UnsafeMutablePointer<UInt8>.allocate(capacity: dataOutAvailable)
                let dataOutMoved = UnsafeMutablePointer<Int>.allocate(capacity: 1)
                
                dataOutMoved.initialize(to: 0)
                
                let cryptStatus = CCCrypt(operation, algoritm, option, keyBytes, keyLength, keyBytes, dataIn, dataInlength, dataOut, dataOutAvailable, dataOutMoved)
                
                var data: Data?
                
                if CCStatus(cryptStatus) == CCStatus(kCCSuccess) {
                    data = Data(bytesNoCopy: dataOut, count: dataOutMoved.pointee, deallocator: .none)
                }
                
                dataOutMoved.deallocate()
                dataOut.deallocate()
                
                if data == nil {
                    return nil
                }
                
                if operation == kCCEncrypt {
                    data = data!.base64EncodedData(options: .lineLength64Characters)
                }
                
                return String(data: data!, encoding: .utf8)
            }
            
            return nil

        }

}