1.utils
const rules = {
// 首位非0的ipv4校验规则
ipv4: /^((0|[1-9]|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}(0|[1-9]|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))$/,
// 首位非0的ipv4和cidr校验规则
// ipv4: /^((0|[1-9]|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}(0|[1-9]|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))(\/([0-9]|[1-2][0-9]|3[0-2])){0,1}$/,
// ipv4的cidr校验
isIpv4Cidr: /^(?:(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}(?:[0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\/([1-9]|[1-2]\d|3[0-2])$/,
strLengthNormal: /^[a-zA-Z0-9_\u4e00-\u9fa5]+$/, // 只含有汉字、数字、字母、下划线,下划线位置不限
// 首位非0的ipv4范围
ipv4Range: /^((0|[1-9]|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))\.){3}(0|[1-9]|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5]))(-([1-9]|([1-9]\d)|(1\d{2})|(2[0-4]\d)|(25[0-5])))$/,
// 域名校验
domainName: /^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/,
// ipv6和cidr校验
ipv6: /^((\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*)(\/(([1-9])|([1-9][0-9])|(1[0-1][0-9]|12[0-8]))){0,1})*$/,
strLengthNormal: /^[a-zA-Z0-9_\u4e00-\u9fa5]+$/, // 只含有汉字、数字、字母、下划线,下划线位置不限
};
2.判断
/* eslint-disable max-len, no-useless-escape */
const isIpV4 = (ip: string): boolean => rules.ipv4.test(ip);
const isIpV6 = (ip: string): boolean => rules.ipv6.test(ip);
const strLengthNormal = (ip: string): boolean => rules.strLengthNormal.test(ip);
const isNumber = (number: string): boolean => rules.isNumber.test(number);
const isIpv4Range = (ip: string): boolean => {
// 判定是否满足ip-[1-255] 结构
if (rules.ipv4Range.test(ip)) {
// 判定范围大小
const [ipStr, range] = ip.split('-');
// 范围值必须小于ip最后一位
return Number(range) >= Number(ipStr.split('.')[3]) ? true : false;
}
return false;
};
// ip转数字
const ip2int = (ip: string) => {
if (ip.includes('-')) {
const currentData = ip.split('-');
const [beginIP, endIP] = currentData;
if (currentData.length !== 2 || !endIP) {
throw new Error('格式错误');
}
if (!isIpV4(beginIP) || !isIpV4(endIP)) {
throw new Error('格式错误');
}
const IpBegin = beginIP.split('.');
const IpEnd = endIP.split('.');
const num1 =
Number(IpBegin[0]) * 256 * 256 * 256 +
Number(IpBegin[1]) * 256 * 256 +
Number(IpBegin[2]) * 256 +
Number(IpBegin[3]);
const num2 =
Number(IpEnd[0]) * 256 * 256 * 256 +
Number(IpEnd[1]) * 256 * 256 +
Number(IpEnd[2]) * 256 +
Number(IpEnd[3]);
if (num1 >= num2) {
throw new Error('格式错误');
}
return true;
}
throw new Error('格式错误');
};
3.暴露:
export {
isUrl,
deleteNullOrUndefinedField,
replaceRouter,
getPageQuery,
deepFlatten,
flatTree,
getWebsocketAddr,
getAuthGrpupIndexPageUrl,
emailChecker,
encodeMobile,
encodeEmail,
strLengthNormal,
domainName,
isIpV4,
isIpv4Cidr,
isIpv4Range,
ip2int,
};
4.使用:
<Form.Item
label="名称"
name="name"
rules={[
{ required: true, message: '名称不能为空!' },
{ max: 32, message: '名称不能超过32个字符!' },
() => ({
validator(_, value) {
if (_isEmpty(value) || strLengthNormal(value)) {
return Promise.resolve();
}
return Promise.reject(new Error('输入格式错误!'));
},
}),
]}
>
<Input placeholder="请输入" />
</Form.Item>
<Form.Item
label="资产组"
name="assetGroup"
rules={[
{ required: true, message: '该项为必填项!' },
{ validator: handleSetValidator },
]}
>
<Input.TextArea
autoSize={{ minRows: 6 }}
placeholder={
'请输入IP地址、域名、多个目标换行符分隔,如 192.168.1.1\n192.168.1.1-192.168.255.255\n192.168.1.0/24\nwww.abc.com'
}
/>
</Form.Item>
5.引用:
// 资产IP校验规则
const handleSetValidator = (rule: any, value: string, callBack: any) => {
if (_isEmpty(value)) {
callBack();
return;
}
const currentVaule = value.split('\n');
currentVaule.forEach((item: string) => {
if (
!isIpV4(item) &&
!domainName(item) &&
!isIpv4Cidr(item) &&
!ip2int(value)
) {
callBack('格式错误');
}
});
callBack();
};