Files
Thijooree-iOS/Thijooree iOS/API/MIB/MibNonce.swift
T

94 lines
3.9 KiB
Swift

import Foundation
enum MibNonce {
/**
* Generates the nonce string from the nonceGenerator token returned by DH key exchange.
*
* Phase 1: for each dash-separated group, take the first token's digits * random(1-99),
* pad to 5 digits, compute digitSum and lastTwo.
* Phase 2: for each group tokens 1-7, apply the operation letter with carry chain.
* Operations: M=(carry%num)+ds+cumSum, A=carry+num+ds+cumSum,
* S=carry²+num+ds+cumSum, X=carry*num+ds+cumSum, C=carry³+num+ds+cumSum
*/
static func generate(_ nonceGenerator: String) -> String {
let groups = nonceGenerator.split(separator: "-", omittingEmptySubsequences: false).map(String.init)
var paddedList: [String] = []
var lastTwoList: [Int] = []
var digitSumList: [Int] = []
var cumSum = 0
// Phase 1
for group in groups {
let tokens = group.trimmingCharacters(in: .whitespaces).components(separatedBy: " ")
let nStr = tokens[0].filter { $0.isNumber }
let n = Int(nStr) ?? 1
let r = Int.random(in: 1...99)
let product = n * r
let padded = String(format: "%05d", product)
let ds = padded.compactMap { $0.wholeNumberValue }.reduce(0, +)
let lt = Int(padded.suffix(2)) ?? 0
paddedList.append(padded)
lastTwoList.append(lt)
digitSumList.append(ds)
cumSum += ds
}
// Phase 2
var resultGroups: [String] = []
for (i, group) in groups.enumerated() {
let tokens = group.trimmingCharacters(in: .whitespaces).components(separatedBy: " ")
var carry = lastTwoList[i]
let ds = digitSumList[i]
var nonceDigits: [Int] = []
for j in 1...7 {
guard j < tokens.count else { nonceDigits.append(0); continue }
let token = tokens[j]
let op = token.filter { $0.isLetter }
let num = Int(token.filter { $0.isNumber }) ?? 1
let value: Int64
switch op {
case "M": value = Int64(carry % num) + Int64(ds) + Int64(cumSum)
case "A": value = Int64(carry) + Int64(num) + Int64(ds) + Int64(cumSum)
case "S": value = Int64(carry) * Int64(carry) + Int64(num) + Int64(ds) + Int64(cumSum)
case "X": value = Int64(carry) * Int64(num) + Int64(ds) + Int64(cumSum)
case "C": value = Int64(carry) * Int64(carry) * Int64(carry) + Int64(num) + Int64(ds) + Int64(cumSum)
default: value = 0
}
let digit = Int(String(abs(value)).suffix(2)) ?? 0
nonceDigits.append(digit)
carry = digit
}
let digitStr = nonceDigits.map { String(format: "%02d", $0) }.joined(separator: " ")
resultGroups.append("\(paddedList[i]) \(digitStr)")
}
return resultGroups.joined(separator: "-")
}
// Random long in [1_000_000, 16_000_000)
static func randomSodium() -> String {
String(Int64.random(in: 1_000_000..<16_000_000))
}
// Random long in [0, 2^40)
static func randomXxid() -> String {
String(Int64.random(in: 0..<(1 << 40)))
}
// Generates persistent App ID in IOS format: "IOS17.2-{15 alphanumeric chars}"
static func generateAppId() -> String {
let chars = Array("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
let random = (0..<15).map { _ in chars.randomElement()! }
return "IOS17.2-\(String(random))"
}
// Random alphanumeric string of given length
static func randomAlpha(_ length: Int) -> String {
let chars = Array("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
return String((0..<length).map { _ in chars.randomElement()! })
}
}