From 7341ead2aade10ea1b833e94275277658741883a Mon Sep 17 00:00:00 2001 From: Edoardo La Greca Date: Mon, 18 Aug 2025 21:09:11 +0200 Subject: switch to multi-module project structure --- lib/src/main/kotlin/IPAddress.kt | 73 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 lib/src/main/kotlin/IPAddress.kt (limited to 'lib/src/main/kotlin/IPAddress.kt') diff --git a/lib/src/main/kotlin/IPAddress.kt b/lib/src/main/kotlin/IPAddress.kt new file mode 100644 index 0000000..8eb7414 --- /dev/null +++ b/lib/src/main/kotlin/IPAddress.kt @@ -0,0 +1,73 @@ +/** + * An IP address (v4 or v6). + */ +class IPAddress { + private var address: Array + private var is4: Boolean + + /** + * @throws NumberFormatException if the IP address follows neither the IPv4 syntax, nor the IPv6 syntax. + */ + constructor(address: String) { + if (isAddressV4(address)) { + this.is4 = true + } else if (isAddressV6(address)) { + this.is4 = false + } else { + throw NumberFormatException() + } + + val split4 = address.split('.') + val split6 = address.split(':') + val bytes: List + if (this.is4) { + bytes = split4.map { it.toUByte(10) } + } else { + val shorts = split6.map { it.toShort(16) } + bytes = shorts.flatMap { + listOf( + it.toInt().and(0xFF00).shr(0x08).toUByte(), + it.toInt().and(0x00FF).toUByte() + ) + } + } + this.address = bytes.toTypedArray() + } + + private fun isAddressV4(address: String): Boolean { + val split4 = address.split('.') + var isOK = split4.size == 4 + isOK = isOK && split4.size == split4.filter { it.matches(Regex("^[0-9]+$")) }.size + return isOK + } + + private fun isAddressV6(address: String): Boolean { + val split6 = address.split(':') + var isOK = split6.size == 8 + isOK = isOK && split6.size == split6.filter { it.contains(Regex("^[0-9][a-f]+$")) }.size + if (isOK) { + return true + } + + // try with "::" + val split6Double = address.split("::") + if (split6Double.size != 2) { + return false + } + val omitted = 8 - split6Double[0].split(':').size - split6Double[1].split(':').size + if (omitted < 0) { + return false + } + return true + } + + override fun toString(): String { + val str: String + if (this.is4) { + str = this.address.joinToString(separator = ".") { it.toString() } + } else { + str = this.address.joinToString(separator = ":") { it.toString() } + } + return str + } +} \ No newline at end of file -- cgit v1.2.3