Думаю, это вопрос к профессионалам. Кажется, что многие люди спотыкаются о проверке IP-адресов при пакетной обработке, просто используя окна, встроенные в функциональные возможности, но реального кода не найти.
В нескольких местах можно найти выражение findstr для идентификации числовой строки, соответствующей четырем последовательностям чисел.
findstr /r "[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*"
Хотя кажется, что нет лучшего способа идентифицировать саму строку (из-за ограниченной поддержки регулярных выражений в findstr), это улавливает слишком ложные срабатывания, такие как 1234.2.3.4
или 999.999.999.999
и, конечно же, 0.0.0.0
.
Нужно будет «только» дополнительно проверить найденную строку, например. с последовательностью циклов for и убедитесь, что каждый найденный октет строки действителен для правил IP.
- первый октет между
1 and 254
- второй и
- третий между
0 and 255
- вперед между
1 and 254
Если затем интегрировать вторую часть проверки в этот код, чтобы определить, был ли найденный IP-адрес одним из 3 частных классов (10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16
или, если быть точным, одним из: от 10.0.0.0 до 10.255.255.255, от 172.16.0.0 до 172.31.255.255 и 192.168.0.0 до 192.168.255.255) это сделает функцию округления. И не забыть про спец 127.x.x.x надо предупредить D).
Чтобы IP4 завершился, переключитесь, чтобы выбрать, будет ли проверяться частный или общедоступный IP-адрес, а возвращаемые значения могут более точно указать, какой тип или даже маски подсети были распознаны:
- первый октет должен быть
255
- второй и
- третий и
- четвертый из
0,128,192,224,240,248,252,254,255
Итак, в целом это будет псевдопроцедура:
функция, принимающая ввод, независимо от того, откуда, только для того, чтобы быть вызванной, принимающая переключатель для использования и возвращающая результат
- использовать коммутаторы для частного или общедоступного диапазона IP-адресов
- validate IP Syntax
- IP verification - recognized range and set return values
- private or
- общий класс
- подсеть
- ...
- IP verification - recognized range and set return values
- установить возвращаемое значение, установить уровень ошибки в зависимости от переключателя
Если код действительно устанавливает удобные для использования коды возврата (например, возвращает распознанный диапазон IP-адресов), это будет функция на все времена для всех, кто имеет дело с IP4 в любом случае. Хотя я сам расширю эти диапазоны IP-адресов, если только функция будет надежно возвращать эти значения «_return», как в примере кода.
Я что-то забыл?
Никто не кодировал это уже?
РЕШЕНИЕ: В соответствии с примером MC ND и кодом обработки коммутатора и маски подсети Aacini я взорвал код, добавил эхо-обработку ошибок и другие случаи - здесь с включенным тестовым примером кода:
@echo off
setlocal enableextensions enabledelayedexpansion
rem try some ip addresses
for %%i in ("1.2.3.4" "0.1.2.3" "250.1024.1.2" "10.0.2.1" "127.0.0.1" "1.2.3.255" "172.16.17.18" "192.168.1.1" "255.128.240.0" "0.0.0.0" "something" "" ) do (
REM 1.2.3.4 is public / 0.1.2.3 is false all / 10.0.2.1 is private / 127.0.0.1 is local / 172.16.17.18 is private / 192.168.1.1 is private / 255.128.240.0 is subnet / 0.0.0.0 is false all (source net)
echo --------------- run one as default case assuming pulic with ret var -------------------
rem call default with a return variable
call :validateIP %%~i ret && echo %%i is valid || echo %%i is invalid
echo return value: !ret!
echo --------------------------------------------
echo --------------- run two with switch public -------------------
rem call with switch public
call :validateIP %%~i /public && echo %%i is valid || echo %%i is invalid
echo return value: !ret!
echo --------------------------------------------
echo ------------ run three with switch private ---------------------
rem call with switch private
call :validateIP %%~i /private && echo %%i is valid || echo %%i is invalid
echo return value: !ret!
echo --------------------------------------------
echo ------------ run four with switch private and ret variable ---------------------
rem call with switch private and return variable
call :validateIP %%~i /private ret && echo %%i is valid || echo %%i is invalid
echo return value: !ret!
echo --------------------------------------------
echo ------------ run five with switch local and ret variable ---------------------
rem call with switch private and return variable
call :validateIP %%~i /local ret && echo %%i is valid || echo %%i is invalid
echo return value: !ret!
echo --------------------------------------------
echo ------------ run six with switch subnet and ret variable ---------------------
rem call with switch private and return variable
call :validateIP %%~i /subnet ret && echo %%i is valid || echo %%i is invalid
echo return value: !ret!
echo --------------------------------------------
echo ------------ run seven with switch source and ret variable ---------------------
rem call with switch private and return variable
call :validateIP %%~i /source ret && echo %%i is valid || echo %%i is invalid
echo return value: !ret!
echo --------------------------------------------
echo ------------ run eight with nothing ---------------------
rem call with switch private and return variable
call :validateIP && echo is valid || echo is invalid
echo return value: !ret!
echo --------------------------------------------
)
exit /b
:validateIP ipAddress [/ipRange] [returnVariable]
rem prepare environment
setlocal enableextensions enabledelayedexpansion
if "%~1"=="" goto USAGE
echo %~1| findstr /b /e /r "[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*" >nul
if errorlevel 1 goto USAGE
:afterusage
rem Initialize ip range as public
set "ipCASE=public"
rem Process switches
set "returnVar=%~2"
rem If second parameter start with slash...
if "%returnVar:~0,1%" equ "/" (
rem It is the /ipRange
set "ipCASE=%returnVar:~1%"
set "returnVar=%~3"
)
rem asume failure in tests : 0=pass 1=fail : same for return/errorlevel
set "_return=1"
set "_returnlevel=1"
set "subNETNumbers=0,128,192,224,240,248,252,254,255"
rem test if address conforms to ip address structure
echo %~1| findstr /b /e /r "[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*" >nul
rem if it conforms to structure, test each octet for range values
if not errorlevel 1 for /f "tokens=1-4 delims=." %%a in ("%~1") do (
if %%a gtr 0 if %%a lss 255 if %%b leq 255 if %%c leq 255 if %%d gtr 0 if %%d leq 254 set "_return=public"
if %%a equ 10 if %%b geq 0 if %%b lss 255 if %%c geq 0 if %%c lss 255 if %%d gtr 0 if %%d leq 254 set "_return=private"
if %%a equ 172 if %%b geq 16 if %%b lss 31 if %%c geq 0 if %%c lss 255 if %%d gtr 0 if %%d leq 254 set "_return=private"
if %%a equ 192 if %%b equ 168 if %%c geq 0 if %%c lss 255 if %%d gtr 0 if %%d leq 254 set "_return=private"
if %%a equ 127 if %%b geq 0 if %%b lss 255 if %%c geq 0 if %%c lss 255 if %%d gtr 0 if %%d leq 254 set "_return=local"
if %%a equ 255 if not "!subNETNumbers:%%b=!" equ "%subNETNumbers%" if not "!subNETNumbers:%%c=!" equ "%subNETNumbers%" if not "!subNETNumbers:%%d=!" equ "%subNETNumbers%" set "_return=subnetmask"
if %%a equ 0 set "_return=sourcenetwork"
)
rem set returnlevels depending on given switch
if "%ipCASE%"=="public" if "%_return%"=="public" (set "_returnlevel=0") else (set "_returnlevel=1")
if "%ipCASE%"=="private" if "%_return%"=="private" (set "_returnlevel=0") else (set "_returnlevel=1")
if "%ipCASE%"=="local" if "%_return%"=="local" (set "_returnlevel=0") else (set "_returnlevel=1")
if "%ipCASE%"=="subnet" if "%_return%"=="subnetmask" (set "_returnlevel=0") else (set "_returnlevel=1")
if "%ipCASE%"=="source" if "%_return%"=="sourcenetwork" (set "_returnlevel=0") else (set "_returnlevel=1")
REM OPTION1 set errorlevel
REM another correct way to set errorlevel would be to REM this line beneath and instead use _returnlevel with exit /b like in line REM OPTION2 - while this is interesting way to set it indirectly
if "%_returnlevel%"=="0" (ver > nul) else (set dummy 2> nul)
:endValidateIP
rem clean and return data/errorlevel to caller
endlocal & ( if not "%returnVar%"=="" set "%returnVar%=%_return%" ) & exit /b
REM OPTION2 endlocal & ( if not "%returnVar%"=="" set "%returnVar%=%_return%" ) & exit /b %_returnlevel%
:usage
echo.
echo Usage: call :validateIP [/ipRange] [returnVariable]
echo.
echo for example: call :validateIP 127.0.0.2 /local ret
echo.
echo if NO switch is given function assumes public,
echo switch and return var are optional
echo errorlevel depends and corresponds on given switch
echo known switches: /public, /private, /local, /subnet, /source
echo return var reflects syntax check, if return var is "1" the input was malformed anyhow
echo.
goto :afterusage
Regex
.NET, а также к другим библиотекам для управления IP-адресами. Это может облегчить эту задачу, если вы сможете это использовать. - person chwarr   schedule 30.11.2013findstr
... - person Aacini   schedule 30.11.2013:-(
- person Aacini   schedule 15.12.2013