Skip to content

Commit

Permalink
Merge pull request #82 from co0ontty/fix/cidr
Browse files Browse the repository at this point in the history
fix: cidr count
  • Loading branch information
phxa1 authored Dec 29, 2023
2 parents 59e66b8 + a8aeb53 commit dfdea4c
Showing 1 changed file with 159 additions and 61 deletions.
220 changes: 159 additions & 61 deletions src/pages/cidr.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,23 @@
import React, { useState, useEffect, useRef } from 'react';
import { TextField, Grid } from '@mui/material';
import MainContent from '@/components/MainContent';
import { Button, TextField, Grid, Typography } from '@mui/material';

import React, { useState, useEffect } from 'react';

function parseCIDR(ip: string, mask: number) {
let ipArray = ip.split('.');
let binaryIp = ipArray
function parseCIDR(ipParts: string[], mask: number) {
let binaryIp = ipParts
.map((oct) => parseInt(oct).toString(2).padStart(8, '0'))
.join('');

let networkAddress = binaryIp.substring(0, mask) + '0'.repeat(32 - mask);
let broadcastAddress = binaryIp.substring(0, mask) + '1'.repeat(32 - mask);

let firstUsable = parseInt(networkAddress, 2) + 1;
let lastUsable = parseInt(broadcastAddress, 2) - 1;
let firstUsable = parseInt(networkAddress, 2);
let lastUsable = parseInt(broadcastAddress, 2);

let netmask = '1'.repeat(mask) + '0'.repeat(32 - mask);
let netmaskOctets = netmask.match(/.{1,8}/g);
let subnetMask = netmaskOctets?.map((oct) => parseInt(oct, 2)).join('.');
let totalUsable = Math.pow(2, 32 - mask) - 2;
let totalUsable = Math.pow(2, 32 - mask);

return {
firstUsableIP: formatIp(firstUsable),
lastUsableIP: formatIp(lastUsable),
Expand All @@ -35,85 +34,184 @@ function formatIp(num: number) {
return parts.join('.');
}

const CIDRCalculator: React.FC = () => {
const [ipAddress, setIpAddress] = useState<string>('192.168.1.1');
const [subnetMask, setSubnetMask] = useState<number>(24);
const CIDRCalculator = () => {
// Separate state variables for each IP segment
const [ipPart1, setIpPart1] = useState('192');
const [ipPart2, setIpPart2] = useState('168');
const [ipPart3, setIpPart3] = useState('1');
const [ipPart4, setIpPart4] = useState('1');
const [subnetMask, setSubnetMask] = useState(24);
const [cidrDetails, setCidrDetails] = useState({
mask: '',
firstUsableIP: '',
lastUsableIP: '',
totalUsable: 0,
});

const calculateCIDR = () => {
const details = parseCIDR(ipAddress, subnetMask);
// Refs for each input field
const ipPartRefs = [
useRef<HTMLInputElement>(null),
useRef<HTMLInputElement>(null),
useRef<HTMLInputElement>(null),
useRef<HTMLInputElement>(null),
];
const subnetMaskRef = useRef(null);
const [ip, setIp] = useState<string>('192.168.100.1');
const [mask, setMask] = useState<number>(24);
useEffect(() => {
const ipParts = [ipPart1, ipPart2, ipPart3, ipPart4];
const details = parseCIDR(ipParts, subnetMask);
setCidrDetails({
...details,
mask: details.mask || '',
});
}, [ipPart1, ipPart2, ipPart3, ipPart4, subnetMask]);

const handleIpPartChange = (value: any, index: number) => {
if (value.includes('.')) {
if (value.includes('/')) {
setIp(value.split('/')[0]);
setMask(value.split('/')[1]);
} else {
setIp(value);
}
const newIpParts = ip.split('.');
console.log(newIpParts, newIpParts.length === 4, !isNaN(mask), mask);
if (newIpParts.length === 4 && !isNaN(mask)) {
for (var i = 0; i < 4; i++) {
const setIpPart = [setIpPart1, setIpPart2, setIpPart3, setIpPart4][i];
console.log(newIpParts[i]);
setIpPart(newIpParts[i]);
}
setSubnetMask(mask);
}
} else {
const numericValue = parseInt(value, 10);

if (!isNaN(numericValue) && numericValue >= 0 && numericValue <= 255) {
const setIpPart = [setIpPart1, setIpPart2, setIpPart3, setIpPart4][
index
];
setIpPart(value);

if (numericValue > 99 && index < 3) {
ipPartRefs[index + 1]?.current?.focus();
}
}
}
};
useEffect(() => {
calculateCIDR();
}, []);

return (
<MainContent>
{/* <Paper elevation={3} sx={{ padding: '20px', marginTop: '20px' }}> */}
<Grid container spacing={2}>
<Grid item xs={10}>
<TextField
fullWidth
label='IP 地址'
variant='outlined'
value={ipAddress}
onChange={(e) => setIpAddress(e.target.value)}
/>
<Grid container spacing={2} alignItems='center' justifyContent='center'>
{[ipPart1, ipPart2, ipPart3, ipPart4].map((part, index) => (
<Grid key={index} item xs={2}>
<TextField
fullWidth
variant='outlined'
value={part}
onChange={(e) => handleIpPartChange(e.target.value, index)}
inputRef={ipPartRefs[index]}
/>
</Grid>
))}
<Grid item xs={0.35}>
/
</Grid>
<Grid item xs={2}>
<TextField
fullWidth
label='掩码位'
label='Subnet Mask'
type='number'
variant='outlined'
value={subnetMask}
onChange={(e) => setSubnetMask(Number(e.target.value))}
inputRef={subnetMaskRef}
/>
</Grid>
<Grid item xs={12}>
<Button
fullWidth
variant='contained'
color='primary'
onClick={calculateCIDR}
>
Calculate
</Button>
<Grid
container
spacing={2}
alignItems='center'
sx={{ mt: '3vh', ml: '4vh' }}
>
<Grid item xs={2}>
总计可用:
</Grid>
<Grid item xs={2}>
<strong>{cidrDetails.totalUsable}</strong>
</Grid>
</Grid>
<Grid
container
spacing={2}
alignItems='center'
sx={{ mt: '3vh', ml: '4vh' }}
>
<Grid item xs={2}>
掩码:
</Grid>
{cidrDetails.mask.split('.').map((part, index) => (
<Grid key={index} item xs={2}>
<TextField
fullWidth
variant='outlined'
type='number'
disabled
value={part}
onChange={(e) => handleIpPartChange(e.target.value, index)}
inputRef={ipPartRefs[index]}
/>
</Grid>
))}
</Grid>
<Grid
container
spacing={2}
alignItems='center'
sx={{ mt: '3vh', ml: '4vh' }}
>
<Grid item xs={2}>
首个可用:
</Grid>
{cidrDetails.firstUsableIP.split('.').map((part, index) => (
<Grid key={index} item xs={2}>
<TextField
fullWidth
variant='outlined'
type='number'
disabled
value={part}
onChange={(e) => handleIpPartChange(e.target.value, index)}
inputRef={ipPartRefs[index]}
/>
</Grid>
))}
</Grid>
<Grid item xs={12}>
<Typography variant='subtitle1' sx={{ mt: '15px', fontSize: '25px' }}>
<a style={{ color: '#99A0B7' }}>子网掩码: </a>
<strong style={{ marginLeft: '5px' }}>{cidrDetails.mask}</strong>
</Typography>
<Typography variant='subtitle1' sx={{ mt: '15px', fontSize: '25px' }}>
<a style={{ color: '#99A0B7' }}>首个可用: </a>
<strong style={{ marginLeft: '5px' }}>
{cidrDetails.firstUsableIP}
</strong>
</Typography>
<Typography variant='subtitle1' sx={{ mt: '15px', fontSize: '25px' }}>
<a style={{ color: '#99A0B7' }}>最后可用: </a>
<strong style={{ marginLeft: '5px' }}>
{cidrDetails.lastUsableIP}
</strong>
</Typography>
<Typography variant='subtitle1' sx={{ mt: '15px', fontSize: '25px' }}>
<a style={{ color: '#99A0B7' }}>所有可用数量: </a>
<strong style={{ marginLeft: '5px' }}>
{cidrDetails.totalUsable}
</strong>
</Typography>
<Grid
container
spacing={2}
alignItems='center'
sx={{ mt: '3vh', ml: '4vh' }}
>
<Grid item xs={2}>
最后可用:
</Grid>
{cidrDetails.lastUsableIP.split('.').map((part, index) => (
<Grid key={index} item xs={2}>
<TextField
fullWidth
variant='outlined'
type='number'
disabled
value={part}
onChange={(e) => handleIpPartChange(e.target.value, index)}
inputRef={ipPartRefs[index]}
/>
</Grid>
))}
</Grid>
</Grid>
{/* </Paper> */}
</MainContent>
);
};
Expand Down

0 comments on commit dfdea4c

Please sign in to comment.