274 lines
8.3 KiB
Swift
Executable File
274 lines
8.3 KiB
Swift
Executable File
|
|
import Foundation
|
|
|
|
extension StringProtocol {
|
|
func substring<S: StringProtocol>(from start: S, options: String.CompareOptions = []) -> SubSequence? {
|
|
guard let lower = range(of: start, options: options)?.upperBound
|
|
else { return nil }
|
|
return self[lower...]
|
|
}
|
|
func substring<S: StringProtocol, T: StringProtocol>(from start: S, to end: T, options: String.CompareOptions = []) -> SubSequence? {
|
|
guard let lower = range(of: start, options: options)?.upperBound,
|
|
let upper = self[lower...].range(of: end, options: options)?.lowerBound
|
|
else { return nil }
|
|
return self[lower..<upper]
|
|
}
|
|
|
|
func index(from: Int) -> Index {
|
|
return self.index(startIndex, offsetBy: from)
|
|
}
|
|
|
|
func substring(with r: Range<Int>) -> String {
|
|
let startIndex = index(from: r.lowerBound)
|
|
let endIndex = index(from: r.upperBound)
|
|
return String(self[startIndex..<endIndex])
|
|
}
|
|
|
|
func hex2decimal() -> Int {
|
|
Int(self, radix: 16) ?? 0
|
|
}
|
|
|
|
func hex2bin() -> String {
|
|
guard let value = Int(self, radix: 16) else {
|
|
return ""
|
|
}
|
|
return String(value, radix: 2)
|
|
}
|
|
|
|
func bin2decimal() -> Int {
|
|
return Int(self, radix: 2) ?? 0
|
|
}
|
|
|
|
func bin2hex() -> String {
|
|
guard let value = Int(self, radix: 2) else {
|
|
return ""
|
|
}
|
|
return String(value, radix: 16)
|
|
}
|
|
|
|
func secondComplementsAmount() -> Int{
|
|
let bin = self.hex2bin()
|
|
let characters = Array(bin)
|
|
var firstComplement = ""
|
|
for c in characters {
|
|
if (c == "0"){
|
|
firstComplement.append("1")
|
|
} else {
|
|
firstComplement.append("0")
|
|
}
|
|
}
|
|
let flipped = Array(firstComplement)
|
|
var isFinish = false
|
|
var secondComplement = ""
|
|
for index in stride(from: firstComplement.count - 1, through: 0, by: -1) {
|
|
let c = flipped[index]
|
|
if (!isFinish){
|
|
if (c == "0"){
|
|
secondComplement.append("1")
|
|
isFinish = true
|
|
} else {
|
|
secondComplement.append("0")
|
|
}
|
|
} else {
|
|
secondComplement.append(c)
|
|
}
|
|
|
|
}
|
|
let second = Array(secondComplement)
|
|
var flipback = ""
|
|
for index in stride(from: secondComplement.count - 1, through: 0, by: -1) {
|
|
let c = second[index]
|
|
flipback.append(c)
|
|
}
|
|
let binhex = flipback.bin2hex()
|
|
return binhex.hex2decimal()
|
|
}
|
|
|
|
func formatCardNumber() -> String {
|
|
let chars = Array(self)
|
|
var cardNumber = ""
|
|
for i in 0..<chars.count {
|
|
cardNumber.append(chars[i])
|
|
if (i == 3) {
|
|
cardNumber.append(" ")
|
|
} else if (i == 7){
|
|
cardNumber.append(" ")
|
|
} else if (i == 11){
|
|
cardNumber.append(" ")
|
|
}
|
|
}
|
|
return cardNumber
|
|
}
|
|
|
|
func formatMaskedCardNumber() -> String {
|
|
let chars = Array(self)
|
|
var cardNumber = ""
|
|
for i in 0..<chars.count {
|
|
if (i == 3) {
|
|
cardNumber.append(chars[i])
|
|
cardNumber.append(" ")
|
|
} else if (i == 7){
|
|
cardNumber.append(chars[i])
|
|
cardNumber.append(" ")
|
|
} else if (i == 8){
|
|
cardNumber.append("*")
|
|
} else if (i == 9){
|
|
cardNumber.append("*")
|
|
} else if (i == 10){
|
|
cardNumber.append("*")
|
|
} else if (i == 11){
|
|
cardNumber.append("*")
|
|
cardNumber.append(" ")
|
|
} else {
|
|
cardNumber.append(chars[i])
|
|
}
|
|
}
|
|
return cardNumber
|
|
}
|
|
|
|
}
|
|
|
|
extension Int {
|
|
func decimal2bin() -> String {
|
|
return String(self, radix: 2)
|
|
}
|
|
|
|
func decimal2hex() -> String {
|
|
return String(self, radix: 16)
|
|
}
|
|
var bin: String {
|
|
String(self, radix: 2).leftPad(with: "0", length: 8)
|
|
}
|
|
}
|
|
|
|
extension UInt8 {
|
|
var bin: String {
|
|
String(self, radix: 2).leftPad(with: "0", length: 8)
|
|
}
|
|
}
|
|
|
|
extension [UInt8] {
|
|
func hexString() -> String {
|
|
return map { String(format: "%02hhx", $0) }.joined()
|
|
}
|
|
}
|
|
|
|
extension String {
|
|
|
|
// static func hexString(_ data: Data) -> String {
|
|
// return data.map { String(format: "%02x", $0) }.joined()
|
|
// }
|
|
|
|
// static func hex2byte(_ str: String) -> Data {
|
|
// var data = Data()
|
|
// var tempStr = str
|
|
// while tempStr.count > 0 {
|
|
// let c = String(tempStr.prefix(2))
|
|
// tempStr = String(tempStr.dropFirst(2))
|
|
// if let num = UInt8(c, radix: 16) {
|
|
// data.append(num)
|
|
// }
|
|
// }
|
|
// return data
|
|
// }
|
|
|
|
func hex2byte() -> Data {
|
|
var data = Data()
|
|
var tempStr = self
|
|
while tempStr.count > 0 {
|
|
let c = String(tempStr.prefix(2))
|
|
tempStr = String(tempStr.dropFirst(2))
|
|
if let num = UInt8(c, radix: 16) {
|
|
data.append(num)
|
|
}
|
|
}
|
|
return data
|
|
}
|
|
|
|
func subString(from: Int, to: Int) -> String {
|
|
guard from >= 0, to >= from, from <= self.count, to <= self.count else {
|
|
return ""
|
|
}
|
|
let startIndex = self.index(self.startIndex, offsetBy: from)
|
|
let endIndex = self.index(self.startIndex, offsetBy: to)
|
|
return String(self[startIndex..<endIndex])
|
|
}
|
|
|
|
func leftPad(with character: Character, length: UInt) -> String {
|
|
let maxLength = Int(length) - count
|
|
guard maxLength > 0 else {
|
|
return self
|
|
}
|
|
return String(repeating: String(character), count: maxLength) + self
|
|
}
|
|
|
|
func stringToBytes() -> [UInt8]? {
|
|
let length = self.count
|
|
if length & 1 != 0 {
|
|
return nil
|
|
}
|
|
var bytes = [UInt8]()
|
|
bytes.reserveCapacity(length/2)
|
|
var index = self.startIndex
|
|
for _ in 0..<length/2 {
|
|
let nextIndex = self.index(index, offsetBy: 2)
|
|
if let b = UInt8(self[index..<nextIndex], radix: 16) {
|
|
bytes.append(b)
|
|
} else {
|
|
return nil
|
|
}
|
|
index = nextIndex
|
|
}
|
|
return bytes
|
|
}
|
|
func localizeString(string: String) -> String {
|
|
guard
|
|
let path = Bundle.main.path(forResource: string, ofType: "lproj"),
|
|
let bundle = Bundle(path: path)
|
|
else {
|
|
return NSLocalizedString(self, comment: "")
|
|
}
|
|
return NSLocalizedString(self, tableName: nil, bundle: bundle,
|
|
value: "", comment: "")
|
|
}
|
|
}
|
|
|
|
|
|
extension String: LocalizedError {
|
|
static let numbers: Set<Character> = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"]
|
|
static let hexSymbols: Set<Character> = ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f", "A", "B", "C", "D", "E", "F" ]
|
|
|
|
public var errorDescription: String? { return self }
|
|
|
|
var isNumeric: Bool {
|
|
guard self.count > 0 else { return false }
|
|
return Set(self).isSubset(of: String.numbers)
|
|
}
|
|
|
|
var isHex: Bool {
|
|
guard self.count > 0 && self.count % 2 == 0 else { return false }
|
|
return Set(self).isSubset(of: String.hexSymbols)
|
|
}
|
|
|
|
subscript(_ range: CountableRange<Int>) -> String {
|
|
let start = index(startIndex, offsetBy: max(0, range.lowerBound))
|
|
let end = index(start, offsetBy: min(self.count - range.lowerBound,
|
|
range.upperBound - range.lowerBound))
|
|
return String(self[start..<end])
|
|
}
|
|
|
|
subscript(_ range: CountablePartialRangeFrom<Int>) -> String {
|
|
let start = index(startIndex, offsetBy: max(0, range.lowerBound))
|
|
return String(self[start...])
|
|
}
|
|
|
|
func deletingPrefix(_ prefix: String) -> String {
|
|
guard self.hasPrefix(prefix) else { return self }
|
|
return String(self.dropFirst(prefix.count))
|
|
}
|
|
func indexInt(of char: Character) -> Int? {
|
|
return firstIndex(of: char)?.utf16Offset(in: self)
|
|
}
|
|
|
|
}
|