skip to Main Content

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?

2

Answers


  1. Chosen as BEST ANSWER

    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
    }
    
    

  2. 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
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search