Home > Enterprise >  Swift: How to convert IPv4 string address to integer and vice-versa
Swift: How to convert IPv4 string address to integer and vice-versa

Time:04-10

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 do it in Swift and what the best way?

CodePudding user response:

There two possible approaches to do it in Swift:

  1. Using old school inet_aton and inet_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))
}
  1. Using IPv4Address from Network
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
}
  • Related