ContentView.swift
//
// ContentView.swift
// Cidr
//
// Created by akira ohmachi on 2021/04/22.
//
import SwiftUI
import GoogleMobileAds
class SelectMask: ObservableObject {
var selectmenu: Array<String> = []
var subnetselected: Int = 0
@Published var selectedMask: String = ""
var selectedIndex: Int = 0 {
didSet {
self.selectedMask = self.selectmenu[self.selectedIndex]
self.subnetselected = self.selectedIndex
}
}
init() {
let array: Array<String> = [
"255.255.255.255(/32)",
"255.255.255.254(/31)",
"255.255.255.252(/30)",
"255.255.255.248(/29)",
"255.255.255.240(/28)",
"255.255.255.224(/27)",
"255.255.255.192(/26)",
"255.255.255.128(/25)",
"255.255.255.0(/24)",
"255.255.254.0(/23)",
"255.255.252.0(/22)",
"255.255.248.0(/21)",
"255.255.240.0(/20)",
"255.255.224.0(/19)",
"255.255.192.0(/18)",
"255.255.128.0(/17)",
"255.255.0.0(/16)",
"255.254.0.0(/15)",
"255.252.0.0(/14)",
"255.248.0.0(/13)",
"255.240.0.0(/12)",
"255.224.0.0(/11)",
"255.192.0.0(/10)",
"255.128.0.0(/9)",
"255.0.0.0(/8)",
"254.0.0.0(/7)",
"252.0.0.0(/6)",
"248.0.0.0(/5)",
"240.0.0.0(/4)",
"224.0.0.0(/3)",
"192.0.0.0(/2)",
"128.0.0.0(/1)",
]
for item in array {
self.selectmenu.append(item)
if self.selectedMask == "" {
self.selectedMask = item
}
}
}
}
struct ContentView : View {
@Environment(\.colorScheme) var colorScheme: ColorScheme
@EnvironmentObject var pub: PublicManager
@ObservedObject var selectMask: SelectMask = SelectMask()
@State private var ipaddress = ""
@State private var ipscore = 0
@State private var text1: String = "0.0.0.0"
@State private var text2: String = "0.0.0.0 ~ 0.0.0.0"
@State private var text3: String = "0.0.0.0"
@State private var text4: String = "0.0.0.0 (single)"
@State private var text5: String = "0.0.0.0"
@State private var text6: String = "0.0.0.0/32"
@State private var text7: String = "255.255.255.255"
@State private var text8: String = "00000000.00000000.00000000.00000000"
@State private var text9: String = "11111111.11111111.11111111.11111111"
@State private var typeConversion: String = "" //型の変更ための、一時保存
@State private var subnet :Int = 0
@State private var ipQuantity: Array<String> = [
"1",
"2",
"4",
"8",
"16",
"32",
"64",
"128",
"256",
"512",
"1,024",
"2,048",
"4,096",
"8,192",
"16,384",
"32,768",
"65,536",
"131,072",
"262,144",
"524,288",
"1,048,576",
"2,097,152",
"4,194,304",
"8,388,608",
"16,777,216",
"33,554,432",
"67,108,864",
"134,217,728",
"268,435,456",
"536,870,912",
"1,073,741,824",
"2,147,483,648",
]
@State private var netMasks: Array<Array<Int>> = [
[0,0,0,0],
[128,0,0,0],
[192,0,0,0],
[224,0,0,0],
[240,0,0,0],
[248,0,0,0],
[252,0,0,0],
[254,0,0,0],
[255,0,0,0],
[255,128,0,0],
[255,192,0,0],
[255,224,0,0],
[255,240,0,0],
[255,248,0,0],
[255,252,0,0],
[255,254,0,0],
[255,255,0,0],
[255,255,128,0],
[255,255,192,0],
[255,255,224,0],
[255,255,240,0],
[255,255,248,0],
[255,255,252,0],
[255,255,254,0],
[255,255,255,0],
[255,255,255,128],
[255,255,255,192],
[255,255,255,224],
[255,255,255,240],
[255,255,255,248],
[255,255,255,252],
[255,255,255,254],
[255,255,255,255]
]
var body: some View {
NavigationView{
GeometryReader { bodyView in
ZStack(alignment: .bottom) {
ScrollView {
VStack(spacing: 0) {
HStack(spacing: 0) {
Spacer()
Text("title")
.foregroundColor(Color.white)
Spacer()
}
.padding(.horizontal, 10)
.padding(.vertical, 3)
.background(ConstValue.colorBg1)
Group {
HStack() {
Text("ipAddress")
.foregroundColor(Color.black)
.font(.subheadline)
TextField("0.0.0.0", text: self.$ipaddress)
.textFieldStyle(RoundedBorderTextFieldStyle())
.cornerRadius(4)
.font(Font(UIFont.monospacedDigitSystemFont(ofSize: 19, weight: .light)))
.keyboardType(.decimalPad)
.onChange(of: self.ipaddress) { value in
if self.ipaddress == "" {
self.calc()
self.ipaddress = ""
} else {
self.calc()
}
}
}
.padding(.horizontal, 10)
.padding(.vertical, 14)
.background(ConstValue.colorBg2)
}
Group {
HStack() {
VStack {
Text("selectMask1")
.foregroundColor(Color.black)
.font(.subheadline)
Text("selectMask2")
.foregroundColor(Color.black)
.font(.subheadline)
}
HStack {
Picker(selectMask.selectedMask, selection: self.$selectMask.selectedIndex) {
ForEach(0..<selectMask.selectmenu.count) { index in
if let name = selectMask.selectmenu[index] {
Text(name)
.tag(name)
.font(Font(UIFont.monospacedDigitSystemFont(ofSize: 16, weight: .light)))
}
}
}
.pickerStyle(MenuPickerStyle())
.onChange(of: self.selectMask.selectedIndex) { value in
if self.ipaddress == "" {
self.calc()
self.ipaddress = ""
} else {
self.calc()
}
}
.padding(6)
.foregroundColor(self.colorScheme == ColorScheme.light ? Color.black : Color.white)
Spacer()
}
.background(self.colorScheme == ColorScheme.light ? Color.white : Color.black)
.cornerRadius(4)
}
.padding(.horizontal, 10)
.padding(.vertical, 14)
.background(ConstValue.colorBg3)
}
Group {
VStack() {
HStack() {
Text("quantity")
.foregroundColor(Color.white)
.font(.subheadline)
Spacer()
}
HStack() {
Text("\(self.ipQuantity[self.selectMask.selectedIndex])")
.foregroundColor(Color.black)
.font(Font(UIFont.monospacedDigitSystemFont(ofSize: 16, weight: .light)))
Spacer()
}
}
.padding(.horizontal, 10)
.padding(.vertical, 3)
.background(ConstValue.colorBg4)
VStack() {
HStack() {
Text("ipAddress")
.foregroundColor(Color.white)
.font(.subheadline)
Spacer()
}
HStack() {
Text(self.text1)
.foregroundColor(Color.black)
.font(Font(UIFont.monospacedDigitSystemFont(ofSize: 16, weight: .light)))
Spacer()
}
}
.padding(.horizontal, 10)
.padding(.vertical, 3)
.background(ConstValue.colorBg5)
VStack(spacing: 0) {
HStack() {
Text("range")
.foregroundColor(Color.white)
.font(.subheadline)
Spacer()
}
HStack() {
Text(self.text2)
.foregroundColor(Color.black)
.font(Font(UIFont.monospacedDigitSystemFont(ofSize: 16, weight: .light)))
Spacer()
}
}
.padding(.horizontal, 10)
.padding(.vertical, 3)
.background(ConstValue.colorBg6)
VStack(spacing: 0) {
HStack() {
Text("network")
.foregroundColor(Color.white)
.font(.subheadline)
Spacer()
}
HStack() {
Text(self.text3)
.foregroundColor(Color.black)
.font(Font(UIFont.monospacedDigitSystemFont(ofSize: 16, weight: .light)))
Spacer()
}
}
.padding(.horizontal, 10)
.padding(.vertical, 3)
.background(ConstValue.colorBg7)
}
Group {
VStack(spacing: 0) {
HStack() {
Text("hostRange")
.foregroundColor(Color.white)
.font(.subheadline)
Spacer()
}
HStack() {
Text(self.text4)
.foregroundColor(Color.black)
.font(Font(UIFont.monospacedDigitSystemFont(ofSize: 16, weight: .light)))
Spacer()
}
}
.padding(.horizontal, 10)
.padding(.vertical, 3)
.background(ConstValue.colorBg8)
VStack(spacing: 0) {
HStack() {
Text("broadcast")
.foregroundColor(Color.white)
.font(.subheadline)
Spacer()
}
HStack() {
Text(self.text5)
.foregroundColor(Color.black)
.font(Font(UIFont.monospacedDigitSystemFont(ofSize: 16, weight: .light)))
Spacer()
}
}
.padding(.horizontal, 10)
.padding(.vertical, 3)
.background(ConstValue.colorBg9)
VStack(spacing: 0) {
HStack() {
Text("cidrNotation")
.foregroundColor(Color.white)
.font(.subheadline)
Spacer()
}
HStack() {
Text(self.text6)
.foregroundColor(Color.black)
.font(Font(UIFont.monospacedDigitSystemFont(ofSize: 16, weight: .light)))
Spacer()
}
}
.padding(.horizontal, 10)
.padding(.vertical, 3)
.background(ConstValue.colorBg10)
}
Group {
HStack(spacing: 0) {
VStack(spacing: 0) {
HStack() {
Text("subnetMask")
.foregroundColor(Color.white)
.font(.subheadline)
Spacer()
}
HStack() {
Text(self.text7)
.foregroundColor(Color.black)
.font(Font(UIFont.monospacedDigitSystemFont(ofSize: 16, weight: .light)))
Spacer()
}
}
}
.padding(.horizontal, 10)
.padding(.vertical, 3)
.background(ConstValue.colorBg11)
HStack(spacing: 0) {
VStack(spacing: 0) {
HStack() {
Text("bit")
.foregroundColor(Color.white)
.font(.subheadline)
Spacer()
}
HStack() {
Text(self.text8)
.foregroundColor(Color.black)
.font(Font(UIFont.monospacedDigitSystemFont(ofSize: 14, weight: .light)))
Spacer()
}
HStack() {
Text(self.text9)
.foregroundColor(Color.black)
.font(Font(UIFont.monospacedDigitSystemFont(ofSize: 14, weight: .light)))
Spacer()
}
}
}
.padding(.horizontal, 10)
.padding(.vertical, 3)
.background(ConstValue.colorBg12)
}
}
Spacer(minLength: 120)
}
.onTapGesture { //画面タップでキーボードを閉じる
UIApplication.shared.closeKeyboard()
}
HStack(spacing: 0) {
Spacer(minLength: 0)
PublicManager.AdView().frame(maxWidth: bodyView.size.width, maxHeight: 50)
Spacer(minLength: 0)
}.background(Color(red: 0.2,green: 0.2,blue: 0.2))
}
}
.background(ConstValue.colorBg)
.navigationBarHidden(true)
}
.navigationViewStyle(StackNavigationViewStyle())
.onAppear { //アプリ起動時に実行
self.calc()
}
}
private func calc() {
//if self.ipaddress == "" {
// self.ipaddress = String(0)
//}
var ips: Array<String> = (self.ipaddress + ".0.0.0.0").components(separatedBy: ".")
var ipAry: Array<Int> = [0,0,0,0]
for i in 0 ... 3 {
if ips[i] == "" {
ips[i] = String(0)
}
self.typeConversion = "000" + ips[i]
ipAry[i] = strToInt(str: typeConversion.suffix(3).description)
if (ipAry[i] < 0) {
ipAry[i] = 0
} else if (ipAry[i] > 255) {
ipAry[i] = 255
}
}
self.text1 = "\(ipAry[0]).\(ipAry[1]).\(ipAry[2]).\(ipAry[3])"
let tmpNum: Int = self.selectMask.selectedIndex
self.subnet = tmpNum
self.calc2(ipAry: ipAry, subnet: tmpNum)
}
private func calc2(ipAry: Array<Int>, subnet: Int) {
var maskXros: Array<Int> = [0,0,0,0]
var nets: Array<Int> = [0,0,0,0]
var netOrs: Array<Int> = [0,0,0,0]
var masks: Array<Int> = [0,0,0,0]
for i in 0 ... 3 {
masks[i] = self.netMasks[32 - subnet][i]
maskXros[i] = (255 - masks[i])
nets[i] = ipAry[i] & masks[i]
netOrs[i] = nets[i] | maskXros[i]
}
self.text2 = "\(nets[0]).\(nets[1]).\(nets[2]).\(nets[3]) ~ \(netOrs[0]).\(netOrs[1]).\(netOrs[2]).\(netOrs[3])"
self.text3 = "\(nets[0]).\(nets[1]).\(nets[2]).\(nets[3])"
if (nets[3] == netOrs[3]) {
self.text4 = "\(nets[0]).\(nets[1]).\(nets[2]).\(nets[3]) (single)"
} else if ((nets[3] + 1) == netOrs[3]) {
self.text4 = "\(nets[0]).\(nets[1]).\(nets[2]).\(nets[3]) ~ \(netOrs[0]).\(netOrs[1]).\(netOrs[2]).\(netOrs[3]) (two)"
} else {
self.text4 = "\(nets[0]).\(nets[1]).\(nets[2]).\(nets[3] + 1) ~ \(netOrs[0]).\(netOrs[1]).\(netOrs[2]).\(netOrs[3] - 1)"
}
self.text5 = "\(netOrs[0]).\(netOrs[1]).\(netOrs[2]).\(netOrs[3])"
self.text6 = "\(nets[0]).\(nets[1]).\(nets[2]).\(nets[3])/\(32 - subnet)"
self.text7 = "\(masks[0]).\(masks[1]).\(masks[2]).\(masks[3])"
self.text8 = "\(to2(num: ipAry[0])).\(to2(num: ipAry[1])).\(to2(num: ipAry[2])).\(to2(num: ipAry[3]))"
self.text9 = "\(to2(num: masks[0])).\(to2(num: masks[1])).\(to2(num: masks[2])).\(to2(num: masks[3]))"
}
private func to2(num: Int) -> String {
let two = String(num, radix: 2)
self.typeConversion = ("00000000" + two).suffix(8).description
return self.typeConversion
}
private func strToInt(str: String) -> Int {
var str2: String = ""
for ch in str {
if ["0","1","2","3","4","5","6","7","8","9"].contains(ch) {
str2 += String(ch)
}
}
return Int("0" + str2)!
}
}
extension UIApplication {
func closeKeyboard() { //キーボードを閉じる
sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil)
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
Group {
ContentView().environmentObject(PublicManager())
}
}
}