ThimraTV/MoviaBox/Base/Networking/Base/SPCryptService.swift
2025-04-27 13:36:31 +08:00

174 lines
4.8 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// SPCryptService.swift
// MoviaBox
//
// Created by on 2025/4/10.
//
import UIKit
class SPCryptService: NSObject {
static let BF_SIZE = 2048
static let EN_STR_TAG = "$"
//
static func randSalt() -> Data {
let size = Int.random(in: 16...64) //
var salt = Data(capacity: size)
for _ in 0..<size {
salt.append(UInt8.random(in: 0...255))
}
return salt
}
//
static func encrypt(_ data: String) -> String? {
guard !data.isEmpty else {
return data
}
// UTF-8
guard let utf8Data = data.data(using: .utf8) else {
return nil
}
//
let salt = randSalt()
let saltLen = UInt8(salt.count)
//
guard let encryptedData = encryptWithSalt(utf8Data, salt: salt) else {
return nil
}
// : [(1)][][]
var fullEncryptedData = Data()
fullEncryptedData.append(saltLen)
fullEncryptedData.append(salt)
fullEncryptedData.append(encryptedData)
// 16
return EN_STR_TAG + fullEncryptedData.hexEncodedString()
}
// 使
static func encryptWithSalt(_ data: Data, salt: Data) -> Data? {
var result = Data(capacity: data.count)
let saltLen = salt.count
for (i, byte) in data.enumerated() {
let saltByte = salt[i % saltLen]
result.append(calSalt(v: byte, s: saltByte))
}
return result
}
//
static func decrypt(_ data: String) -> String? {
guard !data.isEmpty else {
return data
}
//
guard data.hasPrefix(EN_STR_TAG) else {
print("Invalid encoded string.")
return data
}
// 16
let hexString = String(data.dropFirst(EN_STR_TAG.count))
guard let encodedData = NSData(hexString: hexString) as? Data else {
// guard let encodedData = Data(hexString: hexString) else {
print("Invalid hex string.")
return nil
}
guard encodedData.count > 0 else {
print("Empty encoded data.")
return nil
}
//
let saltLen = Int(encodedData[0])
guard encodedData.count > saltLen + 1 else {
print("Invalid encoded data format.")
return nil
}
let salt = encodedData.subdata(in: 1..<(1+saltLen))
let encryptedData = encodedData.subdata(in: (1+saltLen)..<encodedData.count)
//
guard let decryptedData = decryptWithSalt(encryptedData, salt: salt) else {
return nil
}
//
return String(data: decryptedData, encoding: .utf8)
}
// 使
static func decryptWithSalt(_ data: Data, salt: Data) -> Data? {
var result = Data(capacity: data.count)
let saltLen = salt.count
for (i, byte) in data.enumerated() {
let saltByte = salt[i % saltLen]
result.append(calRemoveSalt(v: byte, s: saltByte))
}
return result
}
//
private static func calSalt(v: UInt8, s: UInt8) -> UInt8 {
let r = 255 - v
if s > r {
return s - r - 1
}
return v + s
}
//
private static func calRemoveSalt(v: UInt8, s: UInt8) -> UInt8 {
if v >= s {
return v - s
}
return 255 - (s - v) + 1
}
}
// Data 16/
extension Data {
// 16Data
// init?(hexString: String) {
// let len = hexString.count / 2
// var data = Data(capacity: len)
//
// var index = hexString.startIndex
// for _ in 0..<len {
// let nextIndex = hexString.index(index, offsetBy: 2)
// let byteString = hexString[index..<nextIndex]
//
// guard let num = UInt8(byteString, radix: 16) else {
// return nil
// }
//
// data.append(num)
// index = nextIndex
// }
//
// self = data
// }
// Data16
func hexEncodedString() -> String {
return map { String(format: "%02hhx", $0) }.joined()
}
}