I need to convert IP address (e.g. "127.0.0.1") to integer value and vice-versa for my logger. I've found some samples for ObjC:
- How to convert an IP address from NSString to unsigned int in Objective-C?
- iOS convert IP Address to integer and backwards
How to do it in Swift and what the best way?
CodePudding user response:
There two possible approaches to do it in Swift:
- Using old school
inet_aton
andinet_ntoa
func ipv4_StringToInt(_ value: String) -> UInt32? {
var addr = in_addr()
return inet_aton(value.cString(using: .ascii), &addr) != 0
? UInt32(addr.s_addr)
: nil
}
func ipv4_IntToString(_ value: UInt32) -> String {
let addr = in_addr(s_addr: value)
return String(cString:inet_ntoa(addr))
}
- Using
IPv4Address
fromNetwork
func ipv4_StringToInt(_ value: String) -> UInt32? {
IPv4Address(value)?.rawValue.withUnsafeBytes {
$0.load(as: UInt32.self)
}
}
func ipv4_IntToString(_ value: UInt32) -> String {
let data = withUnsafeBytes(of: value) { Data($0) }
return IPv4Address(data)!.debugDescription
}
How to use:
if let addr = ipv4_StringToInt("127.0.0.1") { // addr = 0x100007F
let ip = ipv4_IntToString(addr)
print(ip) // Outputs: 127.0.0.1
}
CodePudding user response:
This is how I would approach the conversion. It might look a bit over engineering but all properties are useful in other contexts as well:
extension Numeric {
var data: Data {
var bytes = self
return Data(bytes: &bytes, count: MemoryLayout<Self>.size)
}
}
extension Data {
func numeric<T: Numeric>() -> T { withUnsafeBytes { $0.load(as: T.self) } }
}
extension LosslessStringConvertible {
var string: String { .init(self) }
}
The following implementations rely on Network Technology:
import Network
extension StringProtocol {
var ipV4Address: IPv4Address? { .init(string) }
}
extension Data {
var ipV4Address: IPv4Address? { .init(self) }
}
extension IPv4Address {
var uint32: UInt32 { rawValue.numeric() }
}
extension UInt32 {
var ipV4Address: IPv4Address? { data.ipV4Address }
}
Usage:
if let ipV4Address = "10.0.0.1".ipV4Address { // 10.0.0.1
let uint32 = ipV4Address.uint32 // 16777226
let loadedIPv4Address = uint32.ipV4Address! // 10.0.0.1
}