首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为iOS项目快速构建IP 4地址类

为iOS项目快速构建IP 4地址类
EN

Stack Overflow用户
提问于 2018-07-21 15:11:57
回答 1查看 418关注 0票数 0

我试图为IP地址创建我自己的类。我想将它用于iOS项目。我试着找出把代码放在0到255之间的代码。分隔符不能正常工作。我希望它保存一个ip地址,比如192.168.0.1,如果输入400.168.0.1,它应该返回一个错误,或者说,请键入一个真正的ip地址,作为错误的输出之一。我试图创建一个类,当您输入ip地址时,它应该保存在类本身中。我想稍后制作一个iOS应用程序,它将帮助人们了解如何为思科路由器和交换机分配IP地址。基本上想要做一个应用程序,帮助人们使用CIDR ip地址标记,像我在网上找到的这个网页程序,但我几乎不能使用没有互联网连接。http://jodies.de/ipcalc如果我可以编程一个移动应用程序,可以做什么,这个网站将是伟大的工作在我的工作在网络。

代码语言:javascript
复制
import UIKit

class IP4 {
    var ipA: Int?
    var ipB: Int?
    var ipC: Int?
    var ipD: Int?

    func fullIP() -> Int {
        var parts: [Int] = []

        if let ipA = self.ipA {
            parts += [ipA]
        }

        if let ipB = self.ipB {
            parts += [ipB]
        }

        if let ipC = self.ipC {
            parts += [ipC]
        }

        if let ipD = self.ipD {
            parts += [ipD]
        }
        return parts.joined(separator: ".")
    }
}

let ipaddress = IP4()
ipaddress.ipA = 223
ipaddress.ipB = 9
ipaddress.ipC = 50
ipaddress.ipD = 60
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-07-21 20:06:19

这是一个例子,可以在游乐场上进行测试。(在Xcode 9.4.1上测试)

代码语言:javascript
复制
import Foundation

struct IPv4: CustomStringConvertible, Equatable, Hashable {

    enum Errors: Error {
        case invalidFormat
        case octetOutOfRange
    }

    var ipA: UInt8
    var ipB: UInt8
    var ipC: UInt8
    var ipD: UInt8

    init() {
        ipA = 0
        ipB = 0
        ipC = 0
        ipD = 0
    }

    init(_ ipA: UInt8, _ ipB: UInt8, _ ipC: UInt8, _ ipD: UInt8) {
        self.ipA = ipA
        self.ipB = ipB
        self.ipC = ipC
        self.ipD = ipD
    }

    private static let parsingRegex = try! NSRegularExpression(pattern: "^([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})$")
    init(_ ipString: String) throws {
        guard let match = IPv4.parsingRegex.firstMatch(in: ipString, range: NSRange(0..<ipString.utf16.count)) else {
            throw Errors.invalidFormat
        }
        let strA = ipString[Range(match.range(at: 1), in: ipString)!]
        let strB = ipString[Range(match.range(at: 2), in: ipString)!]
        let strC = ipString[Range(match.range(at: 3), in: ipString)!]
        let strD = ipString[Range(match.range(at: 4), in: ipString)!]
        guard
            let ipA = UInt8(strA),
            let ipB = UInt8(strB),
            let ipC = UInt8(strC),
            let ipD = UInt8(strD)
        else {throw Errors.octetOutOfRange}
        self.ipA = ipA
        self.ipB = ipB
        self.ipC = ipC
        self.ipD = ipD
    }

    var description: String {
        return "\(ipA).\(ipB).\(ipC).\(ipD)"
    }

    var networkBytes: Data {
        return Data(bytes: [ipA, ipB, ipC, ipD])
    }

    var hostWord: UInt32 {
        return UInt32(ipA) << 24 + UInt32(ipB) << 16 + UInt32(ipC) << 8 + UInt32(ipD)
    }
}

let ip = IPv4(223, 9, 50, 60)
print(ip) //->223.9.50.60

do {
    let ip = try IPv4("400.168.0.1")
    print(ip)
} catch {
    print(error) //->octetOutOfRange
}
  • 最好使用struct而不是class。因为它的平等应该根据它的内容,而不是它在堆中的地址来判断。
  • IPv4地址由4个八位数组成。你最好使用UInt8,这是不可选的.任何零件都不可能是零。
  • 没有数字类型可以容纳3小数点.如果您想要生成像192.168.0.1这样的符号,那么它需要是一个String

我已经准备了三种类型的输出。仔细想想你想要哪一个。

另外,如果我输入400.168.0.1,它应该返回一个错误。

我向您展示了我的struct的一些扩展,这可能有助于在链接站点中显示类似的功能。

要进行二进制表示:

代码语言:javascript
复制
extension UInt8 {
    var fixedBinaryDescription: String {
        let binStr = String(self, radix: 2)
        return String(repeating: "0", count: 8-binStr.count) + binStr
    }
}

extension IPv4 {
    var binaryDescription: String {
        return "\(ipA.fixedBinaryDescription).\(ipB.fixedBinaryDescription).\(ipC.fixedBinaryDescription).\(ipD.fixedBinaryDescription)"
    }
}
print(ip.binaryDescription) //->11011111.00001001.00110010.00111100

用口罩工作:

代码语言:javascript
复制
extension IPv4 {
    init(maskOfLength len: Int) {
        let highBits: [UInt8] = [
            0b10000000,
            0b11000000,
            0b11100000,
            0b11110000,
            0b11111000,
            0b11111100,
            0b11111110,
            0b11111111,
        ]
        switch len {
        case 0:
            self = IPv4(0, 0, 0, 0)
        case 1...8:
            self = IPv4(highBits[len-1], 0, 0, 0)
        case 9...16:
            self = IPv4(0b11111111, highBits[len-9], 0, 0)
        case 17...24:
            self = IPv4(0b11111111, 0b11111111, highBits[len-17], 0)
        case 25...32:
            self = IPv4(0b11111111, 0b11111111, 0b11111111, highBits[len-25])
        default:
            fatalError()
        }
    }

    func masked(by mask: IPv4) -> IPv4 {
        return IPv4(self.ipA & mask.ipA, self.ipB & mask.ipB, self.ipC & mask.ipC, self.ipD & mask.ipD)
    }
}

let mask = IPv4(maskOfLength: 24)
print(mask.binaryDescription) //->11111111.11111111.11111111.00000000
print(ip.masked(by: mask).binaryDescription) //->11011111.00001001.00110010.00000000

获取IP v4地址类的扩展。

代码语言:javascript
复制
enum IPv4AddressClass {
    case a
    case b
    case c
    case d
    case e
}
extension IPv4 {
    var addressClass: IPv4AddressClass {
        if ipA & 0b1_0000000 == 0b0_0000000 {
            return .a
        } else if ipA & 0b11_000000 == 0b10_000000 {
            return .b
        } else if ipA & 0b111_00000 == 0b110_00000 {
            return .c
        } else if ipA & 0b1111_0000 == 0b1110_0000 {
            return .d
        } else {
            return .e
        }
    }
}
print(ip.addressClass) //->c
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51457349

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档