Files
yattee/Yattee/Core/UserAgentGenerator.swift
2026-02-08 18:33:56 +01:00

134 lines
5.5 KiB
Swift

//
// UserAgentGenerator.swift
// Yattee
//
// Generates random User-Agent strings for HTTP requests.
//
import Foundation
/// Generates random User-Agent strings mimicking common browsers and devices.
enum UserAgentGenerator {
// MARK: - Browser Templates
/// Chrome on Windows
private static let chromeWindows: [(version: String, platform: String)] = [
("120.0.0.0", "Windows NT 10.0; Win64; x64"),
("119.0.0.0", "Windows NT 10.0; Win64; x64"),
("121.0.0.0", "Windows NT 10.0; Win64; x64"),
("122.0.0.0", "Windows NT 10.0; Win64; x64"),
("123.0.0.0", "Windows NT 10.0; Win64; x64"),
]
/// Chrome on macOS
private static let chromeMac: [(version: String, platform: String)] = [
("120.0.0.0", "Macintosh; Intel Mac OS X 10_15_7"),
("119.0.0.0", "Macintosh; Intel Mac OS X 10_15_7"),
("121.0.0.0", "Macintosh; Intel Mac OS X 14_0"),
("122.0.0.0", "Macintosh; Intel Mac OS X 14_1"),
("123.0.0.0", "Macintosh; Intel Mac OS X 14_2"),
]
/// Firefox on Windows
private static let firefoxWindows: [(version: String, platform: String)] = [
("121.0", "Windows NT 10.0; Win64; x64"),
("120.0", "Windows NT 10.0; Win64; x64"),
("122.0", "Windows NT 10.0; Win64; x64"),
("123.0", "Windows NT 10.0; Win64; x64"),
]
/// Firefox on macOS
private static let firefoxMac: [(version: String, platform: String)] = [
("121.0", "Macintosh; Intel Mac OS X 10.15"),
("120.0", "Macintosh; Intel Mac OS X 10.15"),
("122.0", "Macintosh; Intel Mac OS X 14.0"),
("123.0", "Macintosh; Intel Mac OS X 14.1"),
]
/// Safari on macOS
private static let safariMac: [(safariVersion: String, webKitVersion: String, osVersion: String)] = [
("17.2", "605.1.15", "10_15_7"),
("17.1", "605.1.15", "10_15_7"),
("17.3", "605.1.15", "14_2"),
("17.0", "605.1.15", "14_0"),
]
/// Edge on Windows
private static let edgeWindows: [(edgeVersion: String, chromeVersion: String)] = [
("120.0.0.0", "120.0.0.0"),
("119.0.0.0", "119.0.0.0"),
("121.0.0.0", "121.0.0.0"),
("122.0.0.0", "122.0.0.0"),
]
// MARK: - Public Methods
/// Generates a random User-Agent string.
/// - Returns: A User-Agent string mimicking a common browser.
static func generateRandom() -> String {
let browserType = Int.random(in: 0..<10)
switch browserType {
case 0...3: // 40% Chrome
return generateChromeUserAgent()
case 4...5: // 20% Firefox
return generateFirefoxUserAgent()
case 6...7: // 20% Safari
return generateSafariUserAgent()
case 8...9: // 20% Edge
return generateEdgeUserAgent()
default:
return generateChromeUserAgent()
}
}
/// Default User-Agent used when no custom value is set.
static let defaultUserAgent: String = generateRandom()
// MARK: - Private Methods
private static func generateChromeUserAgent() -> String {
let useMac = Bool.random()
if useMac {
guard let config = chromeMac.randomElement() else {
return "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}
return "Mozilla/5.0 (\(config.platform)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/\(config.version) Safari/537.36"
} else {
guard let config = chromeWindows.randomElement() else {
return "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"
}
return "Mozilla/5.0 (\(config.platform)) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/\(config.version) Safari/537.36"
}
}
private static func generateFirefoxUserAgent() -> String {
let useMac = Bool.random()
if useMac {
guard let config = firefoxMac.randomElement() else {
return "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0"
}
return "Mozilla/5.0 (\(config.platform); rv:\(config.version)) Gecko/20100101 Firefox/\(config.version)"
} else {
guard let config = firefoxWindows.randomElement() else {
return "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:121.0) Gecko/20100101 Firefox/121.0"
}
return "Mozilla/5.0 (\(config.platform); rv:\(config.version)) Gecko/20100101 Firefox/\(config.version)"
}
}
private static func generateSafariUserAgent() -> String {
guard let config = safariMac.randomElement() else {
return "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.2 Safari/605.1.15"
}
return "Mozilla/5.0 (Macintosh; Intel Mac OS X \(config.osVersion)) AppleWebKit/\(config.webKitVersion) (KHTML, like Gecko) Version/\(config.safariVersion) Safari/\(config.webKitVersion)"
}
private static func generateEdgeUserAgent() -> String {
guard let config = edgeWindows.randomElement() else {
return "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36 Edg/120.0.0.0"
}
return "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/\(config.chromeVersion) Safari/537.36 Edg/\(config.edgeVersion)"
}
}